Reputation: 27517
I have a method called fetchMerchantData
which calls 3 other async methods. I'm trying to use Promise
so that it doesn't call resp.direct(301, ...)
until all the requests are finished but it's not working.
function fetchOauth2Token(authorizationCode, resp) {
...
request({
url: `https://connect.squareup.com/oauth2/token`,
method: "POST",
json: true,
headers: oauthRequestHeaders,
form: oauthRequestBody,
}, (error, oauthResp, body) => {
if (body.access_token) {
Promise.resolve(fetchMerchantData(body.access_token, body.merchant_id)).then(() => {
console.log("last!"); //<--------------------- this is printing first
resp.redirect(
301,
`myurl.com/blah`
);
});
;
} else {
// TODO find out what to do on failure
resp.redirect(301, `myurl.com/?error=true`);
}
})
}
function fetchMerchantData(access_token, merchant_id){
const updates = {};
request({
url: `https://connect.squareup.com/v1/me/locations`,
method: "GET",
json: true,
headers: {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
"Content-Type": "application/json",
},
}, (error, response) => {
if (!error) {
const locations = response.body;
Promise.all([
saveMerchant(merchant_id, access_token, locations),
saveLocations(merchant_id, locations),
installWebhookForLocations(access_token, locations),
]).then(values => {
console.log("first!"); //<--------------------- this is printing last
return Promise.resolve("Success");
})
}
});
}
And here's an example of the saveMerchant
method which calls firebase:
function saveMerchant(merchant_id, access_token, locations) {
const merchantRef = database.ref('merchants').child(merchant_id);
const location_ids = locations.map(location => location.id);
merchantRef.update({
access_token,
location_ids,
});
}
How would I synchronize this?
== UPDATE ==
This is how my installWebhookForLocations
method looks:
function installWebhookForLocations(access_token, locations){
const locationIds = locations.map(location => location.id);
locationIds.forEach((locationId) => {
request({
url: `https://connect.squareup.com/v1/${locationId}/webhooks`,
method: "PUT",
json: true,
headers: {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
"Content-Type": "application/json",
},
body: ["PAYMENT_UPDATED"],
}, (error) => {
if (!error){
console.log(`Webhook installed for ${locationId}`);
}
});
});
}
Upvotes: 1
Views: 102
Reputation: 24191
Here is an example of saveMerchant that would use a promise.
function saveMerchant(merchant_id, access_token, locations) {
return new Promise(function (resolve, reject) {
const merchantRef = database.ref('merchants').child(merchant_id);
const location_ids = locations.map(location => location.id);
merchantRef.update({
access_token,
location_ids,
}, function (error) {
if (error) return reject(error);
resolve();
});
});
}
To make the above easier, there is a nice Promise library called Bluebird, it has a promisify utility, that you could apply to firebird update method.
Also for your second question were your using forEach, bluebird has a nice utility function called map that you could use instead.
Upvotes: 1