4.13 Advanced Promises

Returning a Promise

var asyncAdd = (a,b) => {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
if (typeof a === 'number' && typeof b === 'number') {
resolve(a + b);
} else {
reject('Arguments must be numbers');
}
}, 1500);
});
};
asyncAdd(5,7).then((res)=>console.log('result:',res),((err)=>console.log(err)));

Promise Chaining

asyncAdd(5,7).then((res)=>{
console.log('result:',res);
return asyncAdd(res, 33);
},((err)=>console.log(err)))
.then((res)=>console.log('result:', res),(err)=>console.log(err));
asyncAdd(5,7).then((res)=>{
console.log('result:',res);
return asyncAdd(res, '33');
},((err)=>console.log(err)))
.then((res)=>console.log('result:', res),(err)=>console.log(err));

This simulates an error. The output is

result: 12
Arguments must be numbers

asyncAdd(5,'7')
.then((res)=>{
console.log('result:',res);
return asyncAdd(res, 33);
},((err)=>console.log(err)))
.then((res)=>console.log('result:', res),(err)=>console.log(err));

This is where things get trickier. The previous promise rejects.
Then the second then actually receives nothing but we still handled it, which yields undefined.

Solution:

asyncAdd(5,'7')
.then((res)=>{
console.log('result:',res);
return asyncAdd(res, 33);
})
.then((res)=>console.log('result:', res))
.catch((err)=>{
console.log(err);
})

Exercise

Wrap geocodeAddress with Promise.

const request = require('request');
var geocodeAddress = (address) => {
return new Promise((resolve, reject) => {
request({
url: `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}`,
json: true // convert string to Json for you
}, (err, res, body) => {
if (err) { // err object only checks machine errors
reject("Unable to connect to Google Servers!");
} else if (body.status === 'ZERO_RESULTS') { // when address not found
reject("Unable to find that address.")
} else if (body.status === 'OK') {
resolve({
address: body.results[0].formatted_address,
latitude: body.results[0].geometry.location.lat,
longitude: body.results[0].geometry.location.lng
});
}
})
})
};
geocodeAddress('19146').then((location) => {
console.log(JSON.stringify(location, undefined, 2));
}, (errMsg) => {
console.log(errMsg);
})