I can't wrap my head around AngularJS' concept of promises.
I have a provider:
var packingProvider = angular.module('packingProvider',[]);
packingProvider.provider('packingProvider',function(){
return{
$get: function($http){
return{
getPackings: function(){
$http.post('../sys/core/fetchPacking.php').then(function(promise){
var packings = promise.data;
return packings;
});
}
}
}
}
});
As you can see, this provides a method getPackings()
, which will return an object
Now, if I use that in my main application to receive the data, the call will be asynchronous, resulting in an issue where I would have to 'wait' for the data:
var packings = packingProvider.getPackings();
console.log(packings); // undefined
How would i do this without refactoring the process into my main controller?
The return value from within your then
method isn't returning when you think it is; it's returning later.
In the statement var packings = packingProvider.getPackings();
the return value is undefined because the promise returned from $http
is asynchronous. That means that the call to $http.post
happens, does not complete, then your function returns. In JS functions that don't return anything return undefined. The post
call completes later and executes return packings;
which gets returned to nowhere.
The getPackings
method should probably return the promise from $http.post
directly. That way any code that wants to use this method can call then
on the promise directly and set the value the way it needs to. In a controller you could assign that promise directly to the $scope
and use it in your view. Here's a nice post that explains that particular feature: http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/
Incidentally, it looks like you've got a long-winded service declaration there; any reason not to shorten it to something like this?
var module = angular.module('packing', []);
module.service('packing', function($http) {
return {
getPackings: function() {
return $http.post('../sys/core/fetchPacking.php');
}
};
});
I'm relatively new to AngularJS but I don't see any gain in all that typing. ( =
Try
var packingProvider = angular.module('packingProvider',[]);
packingProvider.provider('packingProvider',function(){
return{
$get: function($http){
return{
getPackings: function(){
return $http.post('../sys/core/fetchPacking.php').then(function(response){
return response.data; // packings
});
}
}
}
}
});
Then
packingProvider.getPackings().then(function(packings){
console.log(packings);
});
Main idea: you need to return the promise object from the getPackings function. Not sure if you can make the call to it synchronous but it's almost definitely not a great idea to do so. Also, if you want to make "packings" a model object on your controller and use for a two-directional binding, you can safely assign the promise object, which Angular will resolve as soon as data comes through:
$scope.packings = packingProvider.getPackings();
UPDATE
As of 1.2.0-rc.3 promise unwrapping has been deprecated (https://github.com/angular/angular.js/blob/master/CHANGELOG.md#120-rc3-ferocious-twitch-2013-10-14) , so the line of code above will not result in a two-directional binding any more.
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