Reputation: 151
I am having a hard time using promises and passing information between a service and controller.
The code below functions, in that it makes the calls, I get the promises back, I perform work on them, etc. I want to pass status messages back to the controller now, but I can't figure out to return them to the controller.
How can I sync myService
's non-promise response with my controller variable? Or should I just be returning the $q.all
promise back to the controller and then having the controller call the statusService
?
Ideally, I want the controller to just "fire and forget" and wait for a status response so I can update a modal.
function doWork() {
myService.doSomeWork();
// what I'm going for:
// var statusMessage = myService.doSomeWork(sharedDataService.onThisThing);
}
factory.doSomeWork = function() {
var promises = [
queryApi("firstApiCall"),
queryApi("secondApiCall")
];
$q.all(promises)
.then(function(res) {
workService.doSomething(res[0].data, res[1].data);
console.log("response:", res);
// I want to return a string, or object, back to a variable in my controller
//return statusService.getStatusMessage(res[0]);
}, function(err) {
console.log("error:", err);
//return statusService.getStatusMessage(err);
}
);
};
function queryApi(url) {
return $http.get(url);
}
Any help would be appreciated.
Upvotes: 0
Views: 70
Reputation: 48968
In AngularJS, asynchronous services should return a promise. To transform promise data in a service, be sure to return the transformed data to the .then
method handler function:
factory.doSomeWork = function() {
var promises = [
queryApi("firstApiCall"),
queryApi("secondApiCall")
];
̲r̲e̲t̲u̲r̲n̲ $q.all(promises)
.then(function successHandler(res) {
workService.doSomething(res[0].data, res[1].data);
console.log("response:", res);
// I want to return a string, or object, back to a variable in my controller
̲r̲e̲t̲u̲r̲n̲ transformedData;
}, function rejectionHandler(err) {
console.log("error:", err);
̶/̶/̶r̶e̶t̶u̶r̶n̶ ̶s̶t̶a̶t̶u̶s̶S̶e̶r̶v̶i̶c̶e̶.̶g̶e̶t̶S̶t̶a̶t̶u̶s̶M̶e̶s̶s̶a̶g̶e̶(̶e̶r̶r̶)̶;̶
̲t̲h̲r̲o̲w̲ statusService.getStatusMessage(err);
}
);
};
It is important to use a throw statement in rejection handlers. Otherwise the rejected promise will be converted to a successful promise.
In the controller:
function doWork() {
var promise = myService.doSomeWork();
promise.then(function(transformedData) {
console.log(transformedData);
}).catch(function(err) {
console.log(err);
});
// what I'm going for:
// var statusMessage = myService.doSomeWork(sharedDataService.onThisThing);
}
For more information, see You're Missing the Point of Promises.
Upvotes: 1
Reputation: 624
You can do a callback from the service like
factory.doSomeWork = function(callback) {
var promises = [
queryApi("firstApiCall"),
queryApi("secondApiCall")
];
$q.all(promises)
.then(function(res) {
//do a callback
callback(res)
}, function(err) {
console.log("error:", err);
}
);
};
and in your controller you can receive the result
function doWork() {
myService.doSomeWork(function(result){
//handle the result
});
}
Upvotes: 0