Reputation: 581
I have encountered an error running angularjs calling a rest service. Details below.
Here is my app.js code:
angular.module('myApp', []);
angular.module('myApp').factory('weatherService',function($http){
return {
getWeather:function(city,country){
var query = 'city=' + city + '&country=' + country;
return $http.get('http://api.openweathermap.org/data/2.5/weather',{
params: {
q:query
}
}).then(function(response){
return response.data.weather[0].description;
});
}
}
});
angular.module('myApp').controller('WeatherController',
function($scope,weatherService){
$scope.getWeather=function(city,country){
$scope.WeatherDescription = "Fetching...";
weatherService.getWeather(city,country).then(function(data){
$scope.weatherDescription = data;
}, function(data){
$scope.weatherDescription = "Could not obtain data";
});
}
});
html code:
<html ng-app="myApp">
<script src="../js/angular/angular.js" ></script>
<script src="../js/app.js" ></script>
<body ng-controller="WeatherController">
{{getWeather('chicago','usa')}}
</body>
</html>
I get a blank response in the page. When I open the console, I get this error:
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.3.13/$rootScope/infdig?p0=10&p1=%5B%5D
at angular.js:63
at Scope.$digest (angular.js:14281)
at Scope.$apply (angular.js:14506)
at done (angular.js:9659)
at completeRequest (angular.js:9849)
at XMLHttpRequest.requestLoaded (angular.js:9790)
(anonymous) @ angular.js:11607
(anonymous) @ angular.js:8557
$apply @ angular.js:14508
done @ angular.js:9659
completeRequest @ angular.js:9849
requestLoaded @ angular.js:9790
angular.js:63 Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
what could possible be wrong? Anyone can help? I am using version 1.6.1 by the way
Thank you.
Upvotes: 0
Views: 350
Reputation: 38683
You can check if a $digest
is already in progress by checking $scope.$$phase
.
weatherService.getWeather(city,country).then(function(data){
if(!$scope.$$phase) {
$scope.weatherDescription = data;
}
}, function(data){
if(!$scope.$$phase) {
$scope.weatherDescription = "Could not obtain data";
}
});
Upvotes: 0
Reputation: 22323
This is related to how angular $digest
cycles work, and how expressions are evaluated.
You have an expression {{getWeather('chicago','usa')}}
in your HTML. Whenever a $digest
cycle occurs, this expression will be evaluated, and the function will be called.
The function is setting a value $scope.WeatherDescription = "Fetching...";
, then calling an async function. The change in $scope.WeatherDescription
is then causing a new $digest
iteration. The new $digest
iteration is encountering the expression, and firing off the function (again). Even if the data comes back from the promise, it's also going to cause a property on $scope
to change, which is going to cause (another) $digest
, causing (another!) call to the function... This will essentially happen infinitely, which is why angular automatically preempts the processing after 10 cycles.
It is sometimes ok to trigger a function call in an expression, but in order for that to work, the function call needs to return a value, and also needs to not trigger the change to another property on $scope
unrelated to the expression.
In your case, instead of using $scope.WeatherDescription
, you would want to return
the promise from your service.
Upvotes: 1