Reputation: 1315
If I have a service that looks like this:
app.factory('User', function($http, User) {
var User = function(data) {
angular.extend(this, data);
};
User.prototype.create = function() {
var user = this;
return $http.post(api, user.getProperties()).success(function(response) {
user.uid = response.data.uid;
}).error(function(response) {
});
};
User.get = function(id) {
return $http.get(url).success(function(response) {
return new User(response.data);
});
};
return User;
});
How do I, in a controller, get the User
that was created in the get()
function?
Currently what I have is:
app.controller('UserCtrl', function($scope, User) {
$scope.user = null;
User.get($routeParams.rid).success(function(u) {
$scope.user = new User(u.data);
});
});
The issue is that the UserCtrl
is getting the api response, not the value returned from the success()
in the factory. I'd prefer to be making the new user in the factory, as opposed to passing the api response to the controller.
Upvotes: 1
Views: 3769
Reputation: 63
Had similar problem, when i had 'response.data' passed to def.resolve, from controller it throws as undefined. So passed the response directly and it worked.
var def = $q.defer();
$http.get('http://localhost:3000/api/services')
.success(function (response) {
***def.resolve(response);***
})
.error(function (error) {
def.reject(error);
});
return def.promise;
Upvotes: 0
Reputation: 890
Edit: May 5th 2015
I learnt about the deferred anti-pattern while trying to answer this question.
So we can avoid using $q.defer()
and use the following code to achieve the same result.
Service
User.get = function(id) {
return $http.get(url).then(function(response) {
return new User(response.data);
});
};
Controller
User.get($routeParams.rid).then(function(u) {
$scope.user = u;
});
Original Answer below:
I think what you are looking for is the $q
service which allows you to do some post processing on the response from the asynchronous $http
service and then return it to the controller as a promise. Check out the documentation here https://docs.angularjs.org/api/ng/service/$q
So inject the $q
service in your factory and change your User.get
function like below.
User.get = function(id) {
var deferred = $q.defer();
$http.get(url).success(function(response) {
deferred.resolve(new User(response.data));
}).error(function(error) {
deferred.reject(error);
});
return deferred.promise;
};
And then in your controller you can do
User.get($routeParams.rid).then(function(u) {
$scope.user = u;
}, function(error) {
//log error
});
Upvotes: 5
Reputation: 1925
I think your returns are a bit messed up. Personally I would have written it something like this
app.factory('User', function ($http) {
var user = {
new: function (data) {
return $http.post(api, data);
},
get: function (id) {
$http.get(url).success(function (response) {
return user.new(response.data);
});
}
};
return user;
});
Then from inside your controller..
app.controller('UserCtrl', function($scope, User) {
$scope.user = null;
User.get($routeParams.rid).success(function(u) {
$scope.user = u.data;
});
});
Upvotes: 0