I have a route defined in NodeJS Express.
The route calls a function multiple times (which returns a promise). Value returned from these Promises are added to an Array which is then send back to the client using res.json().
The problem that I am facing is that while Promises are getting resolved, res.json() executes as it does not wait for the Promises to return. I think some kind of chaining mechanism would be needed but can't make out how to do it.
Below is my code
app.get('/markers', function(req, res) {
var markers = [];
var marker1 = {"id": 1, "name": "London"};
// Get the lat and lng based on the address
geocoding(marker1.name).then(function(geocode) {
marker1.lat = geocode[0].latitude;
marker1.lng = geocode[0].longitude;
markers.push(marker1);
}, function(error) {
console.log(error);
})
var marker2 = {"id": 2, "name": "Chicago" };
geocoding(marker2.name).then(function(geocode) {
marker2.lat = geocode[0].latitude;
marker2.lng = geocode[0].longitude;
markers.push(marker2);
}, function(error) {
console.log(error);
})
var marker3 = {"id": 3, "name": "Munich" };
geocoding(marker3.name).then(function(geocode) {
marker3.lat = geocode[0].latitude;
marker3.lng = geocode[0].longitude;
markers.push(marker3);
}, function(error) {
console.log(error);
})
// return the lat and lng array to the client
res.json(markers);
})
How can I ensure that ' res.json(markers);' is executed after all the three Promises are resolved.
You just use Promise.all
, which will resolve when all promises are resolved:
app.get('/markers', function(req, res) {
var markers = [];
var marker1 = {"id": 1, "name": "London"};
// Get the lat and lng based on the address
var prom1 = geocoding(marker1.name).then(function(geocode) {
marker1.lat = geocode[0].latitude;
marker1.lng = geocode[0].longitude;
markers.push(marker1);
}, function(error) {
console.log(error);
})
var marker2 = {"id": 2, "name": "Chicago" };
var prom2 = geocoding(marker2.name).then(function(geocode) {
marker2.lat = geocode[0].latitude;
marker2.lng = geocode[0].longitude;
markers.push(marker2);
}, function(error) {
console.log(error);
});
var marker3 = {"id": 3, "name": "Munich" };
var prom3 = geocoding(marker3.name).then(function(geocode) {
marker3.lat = geocode[0].latitude;
marker3.lng = geocode[0].longitude;
markers.push(marker3);
}, function(error) {
console.log(error);
});
// return the lat and lng array to the client
Promise.all([prom1, prom2, prom3]).then(function() {res.json(markers);}).catch(function(err) {console.error(err);});
})
You could await for multiple promises results using Promise.all function.
You could also use Array.prototype.map to prepare an array of promises to reduce code duplication.
And you should properly handle promises rejections.
app.get('/markers', function(req, res, next) {
var markers = [{
id: 1,
name: 'London'
}, {
id: 2,
name: 'Chicago'
}, {
id: 3,
name: 'Munich'
}];
// you could use .map to generate an array of promises
var promises = markers.map(function (marker) {
return geocoding(marker.name);
})
// and then use Promise.all to await their results
Promise.all(promises).then(function (geocodes) {
// you could use .map again to generate resulting json
res.json(geocodes.map(function (geocode) {
return {
lat: geocode[0].latitude,
lng: geocode[0].longitude
}
}));
}).catch(next) // handle promise rejection
})
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