LittleWhiteFairy
LittleWhiteFairy

Reputation: 97

AngularJS - scope variable does not get updated from method

I'm totally new to AngularJs and I have this problem I do not understand. I have two methods. The first one takes some data from a webservice and puts in in a variable defined in the scope. But when I want to use that variable in the second method it is undefined. Can someone help me understand why this is happening and provide a solution?

var myApp= angular.module( "myApp", [] );

myApp.controller("myAppController",
function( $scope ) {
$scope.getAll = function(){
    $.ajax({
        type: "GET",
        dataType: "jsonp",
        contentType: "application/json; charset=utf-8",
        url: ..something...,
        success: function (parameters) {
            $scope.profiles = angular.copy(parameters);  <-- correct data is returned
            $scope.$apply();
        },
        error: function () {
            alert("Error calling the web service.");
        }
    });
}
$scope.getCategories = function(){
    var all = $scope.profiles;    <-- At this point profiles is empty
    ...
}
    $scope.getAll();
    $scope.getCategories();
}

Upvotes: 0

Views: 1405

Answers (4)

laurent
laurent

Reputation: 90746

When you call getCategories(), getAll() hasn't finished yet, which is why profiles is empty. There are several ways to solve this. The best way would be to use promises the built-in $http service.

If you prefer to use jQuery, you can add a watcher on the profiles variable and only when it's populated run the getCategories().

Something like this should work:

$scope.getAll = function(){
    $.ajax({
        type: "GET",
        dataType: "jsonp",
        contentType: "application/json; charset=utf-8",
        url: ..something...,
        success: function (parameters) {
            $scope.profiles = angular.copy(parameters);  <-- correct data is returned
            $scope.$apply();
        },
        error: function () {
            alert("Error calling the web service.");
        }
    });
}

$scope.getCategories = function(){
    var all = $scope.profiles;

}

// Wait for the profiles to be loaded
$scope.watch('profiles', function() {
    $scope.getCategories();
}

$scope.getAll();

Upvotes: 2

Guillaume86
Guillaume86

Reputation: 14400

Use the $http service and promises:

$scope.profiles = $http.jsonp(url).then(function(r){ return r.data; });
$scope.categories = $scope.profiles.then(function(profiles) {
  var params = { }; // build url params
  return $http.jsonp(url, { params: params }).then(function(r){ return r.data; });
});

Upvotes: 2

JoeG
JoeG

Reputation: 13182

Why are you using a jQuery ajax request in angular? If you write jQuery style code and wrap it angular, you're going to have a bad time...

Here is an angularised version:

myApp.controller("myAppController",
function( $scope, $q, $http ) {

  $scope.getAll = function(){
    var deferred = $q.defer();
    $scope.profiles = deferred.promise;
    $http.jsonp('your url').then(function(data) {
      deferred.resolve(data);
    }); 
  });

  $scope.getCategories = function(){
    $q.when($scope.profiles).then(function(profiles) {  
       ... <-- At this point profiles is populated
    });    
  }

  $scope.getAll();
  $scope.getCategories();
}

Upvotes: 1

NilsH
NilsH

Reputation: 13821

There is no guarantee that getAll has completed before getCategories is invoked, since it is an asynchronous request. So if you want to sequentially invoke getAll and getCategories, you should invoke getCategories inside the success callback of getAll. You could also look into promises for a neater way of chaining asynchronous callbacks (I assume you're using jQuery since you're calling $.ajax).

...
<snipped some code>

success: function(parameters) {
    // snipped more code
    $scope.getCategories();
}

(and if you're using jQuery promises)

$.ajax(ajaxCallOneOpts).then($.ajax(ajaxCallTwoOpts));

Neither are very "Angularish" though, so you might want to look into some of the provided services for working with http/rest resources instead of using jQuery.

Upvotes: 1

Related Questions