Johnny Bronson
Johnny Bronson

Reputation: 13

Angular $http returns data but doesn't apply to scope

In angular, I have this factory

.factory('Users', function($http) {
  var users = [];

  return {
    getUsers: function() {
      return $http.get("data.json")
        .then(function(response) {
          users = response.data;
          return users;        
        });
    },
    getUser: function(id) {
      for (i = 0; i < users.length; i++) {
        if (users[i].id == id) {
          return users[i];
        }
      }
      return null;
    }
  }
})

And then load that data in my controller

.controller('SessionsCtrl', function($scope, Users) {
  $scope.users = Users.getUsers();
})

If I console.log the response from the http request, I am getting the data, but for some reason, the scope data won't update.

I've seen examples where the controller would look like this

Users.getUsers().then(function(data) {
    $scope.users = data;
});

but from my understanding, I shouldn't need to since $http is already returning a promise. Am I missing something? Do I need to involve $q at all?

Upvotes: 1

Views: 779

Answers (2)

ms87
ms87

Reputation: 17492

This will work:

 getUsers: function() {
      return $http.get("data.json");
    },

and:

Users.getUsers().then(function(data) {
    $scope.users = data.data;
});

What you wrote however will not work, simply because you can't directly return a result from an operation that will complete later such as a $http call. The problem with this:

 getUsers: function() {
      return $http.get("data.json")
        .then(function(response) {
          users = response.data;
          return users;        
        });
    },

Is that by the time the return users; line executes the ajax call is still in progress and nothing has been returned yet, so you will get nothing for users. For what you're looking to do I would go about using a callback:

 getUsers: function(callback) {
        $http.get("data.json")
         .then(function(response) {
          users = response.data;
          callback(users);        
        });
    },

Usage:

Users.getUsers(function(data) {
    $scope.users = data;
});

Upvotes: 3

sma
sma

Reputation: 9597

Your getUsers function is still returning a promise because its returning the value of $http.get. So, yes, the value you're assigning to $scope.users is a promise. You'll have to handle the promise to set the value to $scope.users according to your example above:

Users.getUsers().then(function(data) {
    $scope.users = data;
});

Upvotes: 0

Related Questions