2015-06-20 3 views
0

У меня возникли проблемы с пониманием источника ошибки, так как html-сторона захватывает такие вещи, как list[3].main.temp, просто отлично, но во втором цикле функции generateList я получаю право ошибки на $scope.list[i].main.temp который говоритTypeError: Невозможно прочитать свойство «0» неопределенного в угловом приложении

TypeError: Cannot read property '0' of undefined =\

код должен взять список из 30 городов, выбрать случайным образом 10 и отображать их текущую температуру.

var WeatherApp = angular.module("WeatherApp", ["ngRoute", "ngResource"]). 
config(function ($routeProvider) { 
    $routeProvider. 
     when('/', { controller: ListCtrl, templateUrl: 'list.html' }). 
     otherwise({ redirectTo: '/' }); 
}); 

WeatherApp.factory('City', function ($resource) { 
return $resource('/api/City/:id', { id: '@id' }, {update: { method: 'PUT'}}); 
}); 

var ListCtrl = function ($scope, $location, City, $http) { 
$scope.city = City.query(); 

$scope.units = 'metric'; 
$scope.appId = ''; 
$scope.displayNum = 10; 
$scope.display = []; 
$scope.display.temp = []; 

$scope.generateList = function() { 
    $scope.exp = City.query(function (exp) { 
     shuffle(exp); 
     $scope.cityIdAr = []; 
     for (var i = 0; i < $scope.displayNum; ++i) { 
      $scope.display.push($scope.exp[i]); 
      $scope.cityIdAr.push($scope.exp[i].CityId); 
     }; 
     $scope.cityId = $scope.cityIdAr.join(); 
     $scope.getWeather(); 
     for (var i = 0; i < $scope.displayNum; ++i) { 
      $scope.display.temp.push($scope.list[i].main.temp); 
     }; 
    }); 
}; 

function shuffle(ob) { 
    for (var j, x, i = ob.length; i; j = Math.floor(Math.random() * i), x = ob[--i], ob[i] = ob[j], ob[j] = x); 
    return ob; 
}; 

$scope.getWeather = function() { 
    var url = 'http://api.openweathermap.org/data/2.5/group'; 
    $http.jsonp(url, { 
     params: { 
      id: $scope.cityId, 
      APPID: $scope.appId, 
      units: $scope.units, 
      callback : 'JSON_CALLBACK' 
     } 
    }).success(function (data, status, headers, config) { 
     $scope.data = data; 
     $scope.list = data.list; 
     }); 
}; 


$scope.generateList(); 
}; 
+0

[Как вернуть ответ от асинхронного вызова?] (Http://stackoverflow.com/questions/14220321/ как-к-ответ-ответ-от-асинхронного вызова) – Andreas

ответ

0

Проблема может заключаться в том, что $scope.list не определено до тех пор, пока не будет выполнен обратный вызов. Вы можете вернуть обещание от $scope.getWeather и разрешить его в $scope.generateList, а затем выполнить цикл for, когда данные извлекаются (внутри обратного вызова), например.

Возвращение обещание от $scope.getWeather:

$scope.getWeather = function() { 
    ... 
    return $http.jsonp(...) 
} 

, а затем в $scope.generateList:

... 
$scope.getWeather().success(function(data, status, headers, config) { 
    $scope.data = data; 
    $scope.list = data.list; 
    for (var i = 0; i < $scope.displayNum; ++i) { 
    $scope.display.temp.push($scope.list[i].main.temp); 
    }; 
} 

или что-то вдоль этих линий.

+0

, что действительно сработало, спасибо большое! –

+0

все еще изучаю, что думаю, мне нужно повернуть взгляд, чтобы пообещать :) –

+0

Рад, что я мог бы помочь. Работа с обещаниями довольно прямолинейна. Вы мгновенно получите его. Важная часть - это то, что ваши контроллеры тонкие. Попробуйте использовать службы для извлечения данных. – chris

0

$ scope.display является список использовать другую переменную

var WeatherApp = angular.module("WeatherApp", ["ngRoute", "ngResource"]). 
config(function ($routeProvider) { 
    $routeProvider. 
     when('/', { controller: ListCtrl, templateUrl: 'list.html' }). 
     otherwise({ redirectTo: '/' }); 
}); 

WeatherApp.factory('City', function ($resource) { 
return $resource('/api/City/:id', { id: '@id' }, {update: { method: 'PUT'}}); 
}); 

var ListCtrl = function ($scope, $location, City, $http) { 
$scope.city = City.query(); 

$scope.units = 'metric'; 
$scope.appId = ''; 
$scope.displayNum = 10; 
$scope.display = []; 
$scope.temp = []; 

$scope.generateList = function() { 
    $scope.exp = City.query(function (exp) { 
     shuffle(exp); 
     $scope.cityIdAr = []; 
     for (var i = 0; i < $scope.displayNum; ++i) { 
      $scope.display.push($scope.exp[i]); 
      $scope.cityIdAr.push($scope.exp[i].CityId); 
     }; 
     $scope.cityId = $scope.cityIdAr.join(); 
     $scope.getWeather(); 
     for (var i = 0; i < $scope.displayNum; ++i) { 
      $scope.temp.push($scope.list[i].main.temp); 
     }; 
    }); 
}; 

function shuffle(ob) { 
    for (var j, x, i = ob.length; i; j = Math.floor(Math.random() * i), x = ob[--i], ob[i] = ob[j], ob[j] = x); 
    return ob; 
}; 

$scope.getWeather = function() { 
    var url = 'http://api.openweathermap.org/data/2.5/group'; 
    $http.jsonp(url, { 
     params: { 
      id: $scope.cityId, 
      APPID: $scope.appId, 
      units: $scope.units, 
      callback : 'JSON_CALLBACK' 
     } 
    }).success(function (data, status, headers, config) { 
     $scope.data = data; 
     $scope.list = data.list; 
     }); 
}; 


$scope.generateList(); 
}; 

enter image description here

Смежные вопросы