Angular http returns $$state object

wdphd picture wdphd · Jan 26, 2015 · Viewed 34.2k times · Source

I have the following factory defined:

angular.module("account").factory("users",["$http",
    function(a){
      return {
         getUser: function(){
            return a.get("/user/me").then(function(r){
                return r.data;
            });
        }
    };
  }
]);

And my controller:

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        a.user = u.getUser();
        console.log(a.user);
}]);

Here's the console.log:

 d {$$state: Object, then: function, catch: function, finally: function} $$state: Object status: 1 value: Object user: Object__v: 0 _id: "54c1fg29f36e117332000005" temp: "1ce3793175e0b2548fb9918385c2de09"  __proto__: Object __proto__: Object __proto__: Object __proto__: Object

The above code is returning a state object instead of the user object. But from the log, the state object has the user object within value. How do i get the user object? Or am i doing this completely wrong?

I know the other way is to return the $http.get and call the then() method within controller. But I'll be using the user object frequently and if i'm calling the then() method in controller, its almost same as using the $http.get in controller instead of the factory.

Answer

Benjamin Gruenbaum picture Benjamin Gruenbaum · Jan 26, 2015

JavaScript I/O is usually, including in this case asynchronous. Your getUser call returns a $q promise. In order to unwrap it you have to chain to it and then unwrap it as such:

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        u.getUser().then(function(user){
            a.user = user;
            console.log(a.user);
        });
}]);

If you're using routing you might also want to look into the resolve option in the route. Also see this related question.