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.
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.
angular.module("account").factory("users",["$http",
function(a){
var factObj = {
user: null,
getUser: function(){
return a.get("/user/me").then(function(r){
factObj.user = r.data;
});
}
factObj.getUser();
return factObj;
};
}
]);
angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
function(a,u){
a.userService = u;
}]);
In your view
<div ng-controller="TestCtrl as test">{{test.userService.user}}</div>
Edits based on comments, true this would not work with the controller or view as you probably had them, but this pattern works well and removes the need to have .then in every controller that may re-use the data.
Typically storing your model in the factory or service that deals with fetching the data makes for an easier path to getting the data into every view where you need it. Down side here is you'd be fetching the user when this factory is referenced instead of explicitly firing the getUser function from the controller. If you want to get around that you can store the promise from the first time it's requested in the getUser function and just return that promise for all subsequent calls if it's already set, this way you can call getUser multiple times without repeating the API request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With