Hingle McJingleberry
Hingle McJingleberry

Reputation: 581

angular js infinite iteration error

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

Answers (2)

Ramesh Rajendran
Ramesh Rajendran

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

Claies
Claies

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

Related Questions