-1

I am following an AngularJS tutorial that uses $resource to retrieve JSON data from an API call. For the purpose of understanding, I tried to replace the $resource code with $http code and I encountered a scope problem. Logging $scope.weatherResult outside of .success() results in undefined. Why is that the case? The view receives the data just fine.

Also,

// $scope.weatherAPI = $resource(
     'http://api.openweathermap.org/data/2.5/forecast/daily',
     { callback: 'JSON_CALLBACK' }, { get: { method: 'JSONP' }}
   );

// $scope.weatherResult = $scope.weatherAPI.get({ q: $scope.city, cnt: 2});


$http.get('
  http://api.openweathermap.org/data/2.5/forecast/daily'
    + '?q='
    + $scope.city
    + '&'
    + 'cnt=2'
  )
  .success(function(data) {
    $scope.weatherResult = data;
  })
  .error(function(error) {
    console.log(error);
  });

console.log($scope.weatherResult);
Raphael Rafatpanah
  • 19,082
  • 25
  • 92
  • 158
  • possible duplicate of [How to return the response from an Ajax call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – PSL Dec 18 '14 at 17:45
  • Here is another one.. http://stackoverflow.com/questions/12505760/processing-http-response-in-service You will find so many examples on how to use promises and deal with async calls. – PSL Dec 18 '14 at 18:00

2 Answers2

1

Because $http is asynchronous. $scope.weatherResult is defined only when the http response is available.

See for example http://code.tutsplus.com/tutorials/event-based-programming-what-async-has-over-sync--net-30027, or better, as PSL says: How do I return the response from an asynchronous call?

You can use $watch to be informed:

$watch('weatherResult',function(newValue,oldValue)) {
..
}
Community
  • 1
  • 1
Thierry
  • 5,133
  • 3
  • 25
  • 30
  • In previous versions of AngularJS, you could wrap code inside of a $scope.apply(). That would then tell Angular to watch for changes in the data and apply them as they occur. I'm not sure how to do something like that in the new verion, however, would that not work in this situation? – Raphael Rafatpanah Dec 18 '14 at 17:53
1

When you write

.success(function(data) { $scope.weatherResult = data; })

in your program, you are asking the remaining part of your code to continue its execution with a promise. In this case console.log($scope.weatherResult); will be executed just after your $http.get() method without waiting for the response from the http request.

Hence, console.log($scope.weatherResult); will be executed even before the API response is received.

Note that $scope.weatherResult is defined inside .success(), so until the response is a success, Angular has no idea about $scope.weatherResult hence the console gives undefined. It will be undefined even in case of an error.

To view the response of server, you can log it well inside success block.

.success(function(data) { $scope.weatherResult = data; console.log("$scope.weatherResult = ",$scope.weatherResult); })

Aniket Sinha
  • 6,001
  • 6
  • 37
  • 50