Reputation: 2103
In Angular (and other JavaScript frameworks), data from an http request is retrieved async using a promise and can be set to a variable using a callback. Simple enough. But I'm getting tired of writing code that looks like this:
service.getWidgetsAsync(function (result) { vm.widgets = result.data });
Is there any way that I haven't thought of to write the above more like this....?
vm.widgets = service.getWidgetsAsync();
"No" is probably a valid answer. :-)
(Example of the getWidgetsAsync added to clarify: )
function getWidgetsAsync(callback) {
$http.get(APPBASEURL + 'Foo/GetWidgets')
.then(function(result) {
callback(result);
});
}
Upvotes: 0
Views: 180
Reputation: 29214
Yes and no... You can use angular $resource
which will initially populate the variable with an empty object and fill in the details when it gets the results so your code will look like you want, but the values aren't filled in until the call completes so you can't immediately assume you have data.
angular.module('MyApp')
.factory('WidgetResource', ['$resource', function ($resource) {
return $resource('/api/widgets',
{
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
});
}]);
Then in your controller:
var vm.widgets = WidgetResource.query();
Any bindings or watches you do will fire when the data is received. For instance if you have a list of widgets in an ng-repeat
they will show up when the ajax call completes, but if you check the length of the widgets array immediately after the line above in your code it will be zero.
Upvotes: 1
Reputation: 101662
The problem is that you are defeating the whole point of promises by involving callbacks. Return the promise instead of using it to call a callback:
function getWidgetsAsync() {
return $http.get(APPBASEURL + 'Foo/GetWidgets');
}
Then you can write code like this:
service.getWidgetsAsync()
.then(function (result) {
vm.widgets = result.data;
// do more stuff with vm.widgets
})
.then(/* do other things after the function above is done */);
The answer to your question is no, you can't use the result of an asynchronous operation immediately after you call it. If you could, it wouldn't be asynchronous.
Upvotes: 2