I want to return a zipcode before I call a 2nd service, so that -- from what I thought I know -- I can wrap in a promise, and then ask for the promise later. So I figured I would just place my 2nd service inside the promise of the 1st service. But chaining promises this way is not being friendly.
Angular factory is called up and inside the factory method:
var userGeoPromise = userService.getGeoposition().then(function (geoposition) {
vm.geoposition = geoposition;
return addressService.reverseGeocode(geoposition.coords);
}).then(function (data) {
vm.currentLocation = googleService.googleAddressComponentsToAddress(data.results[0]);
zipCodeCurrent = vm.currentLocation.zip;
});
Notice 2 things above:
var userGeoPromise
zipCodeCurrent
is set which contains the zipcode Promise Testing works fine:
userGeoPromise.then( function() {
console.log('should always show', zipCodeCurrent);
});
2nd service call:
userGeoPromise.then( function() {
var serviceBase = "http://localhost:2295/api/getservicezip/"+ zipCodeCurrent;
var serviceZipPromise = $http.get(serviceBase);
return serviceZipPromise.then(function (results) {
console.log('serviceZipPromise', results);
return results.data;
});
});
But now the site modal just spins when I put the serviceZipPromise.then
... inside the other promise.
Switch the order and add in 2 separate error handlers ( which is a good practice btw)
var serviceZipPromise = $http.get(serviceBase); // call up
return serviceZipPromise.then(function (results) {
console.log('should always show', zipCodeCurrent);
userGeoPromise.then(function () {
//console.log('serviceZipPromise', results);
console.log('inside servicezip ', zipCodeCurrent);
}, function (err) { // error from userGeoPromise
console.log(err);
});
return results.data; // THIS will return the data
}, function (err) { // outer error, this was switched
console.log(err);
});
This should not error, but for your real serviceBase
to end up using the zip code, u might have to execute it a bit later
UPDATE answer for you
// created part of the api call
var xserviceBase = "http://localhost:2295"; // this looks to be your base
return userGeoPromise.then(function(){
return $http.get(xserviceBase + '/api/getserviceablezip/' + zipCodeCurrent).then(function(results){
return results.data;
})
});
Yes, I know that the 3 returns look a bit nasty, but it should work
In a then
callback you should return the result value, not assign it to zipCodeCurrent
(or any other variable). You did this correctly in the first then
callback, but you should apply the same principle in the second:
var userGeoPromise = userService.getGeoposition().then(function (geoposition) {
vm.geoposition = geoposition;
return addressService.reverseGeocode(geoposition.coords);
}).then(function (data) {
vm.currentLocation = googleService.googleAddressComponentsToAddress(data.results[0]);
return vm.currentLocation.zip; // *** return it
});
NB: I did not touch the assignments to the properties of vm
, but normally you should avoid mutating variables which (apparently) exist outside of the scope of these callback functions.
The Promise test would look like this:
userGeoPromise.then( function(zipCodeCurrent) { // *** add the argument
console.log('should always show', zipCodeCurrent);
});
The 2 nd service has a nested then
call, which is something to avoid. Instead of calling a then
on a nested, intermediate promise, return that promise, and apply the then
on the main promise chain:
userGeoPromise.then( function(zipCodeCurrent) { // *** add the argument as in the test
var serviceBase = "http://localhost:2295/api/getservicezip/"+ zipCodeCurrent;
return $http.get(serviceBase); // *** return the promise
}).then( function (results) { // *** move the then-callback to the outer chain
console.log('serviceZipPromise', results);
return results.data;
}).catch( function (error) { // *** add error handling at the end of the chain
console.log('error occurred:', error);
});
Note how the nesting level is never more than 1.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.