FAQ: JavaScript Promises - Chaining Multiple Promises

firstPromiseFunction()
.then((firstResolveVal) => {
return secondPromiseFunction(firstResolveVal);
})
.then((secondResolveVal) => {
console.log(secondResolveVal);
});

hey @mtf pls help me to understand this . In the previous exercises we were told that chaining .then() functions, the second .then() is for the failure handler. How do I know in the code snippet above if the second .then() is for success or failure?

The first then will return a Promise, else it will default to the .catch() which is not there present, but would be.

Hi!

I just completed the async…await lesson and started to wonder how would this exercise be re-written using async…await? Can we even use it in this case?

I’m wondering the same thing. Hi @mtf , would you mind answering this question as well? It would help me a lot. Thanks in advance!

As stated in the narrative, chained responses hand their return to the next link in the chain to use as an argument in that one.

When writing return lines in the then blocks, why is the parametre for processPayment and shipOrder always ‘resolvedValueArray’? In library.js, only processPayment had resolvedValueArray as a parameter, so why does shipOrder also have it in app.js?

My code gives this error:
$ node app.js
All of the items are in stock. The total cost of the order is 35.97.
/home/ccuser/workspace/promises-chaining-promises/library.js:41
let hasEnoughMoney = order.giftcardBalance >= total;
^

TypeError: Cannot read property ‘giftcardBalance’ of undefined
at Timeout.setTimeout [as _onTimeout] (/home/ccuser/workspace/promises-chaining-promises/library.js:41:30)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
$ node app.js
All of the items are in stock. The total cost of the order is 35.97.
/home/ccuser/workspace/promises-chaining-promises/library.js:41
let hasEnoughMoney = order.giftcardBalance >= total;
^

TypeError: Cannot read property ‘giftcardBalance’ of undefined
at Timeout.setTimeout [as _onTimeout] (/home/ccuser/workspace/promises-chaining-promises/library.js:41:30)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)

EDIT: I clicked to view solution and I realised that the mistake was that instead of:

.then((resolvedValueArray) => {
return processPayment(resolvedValueArray);
})

I wrote:

.then((resolvedValueArray) => {
// Write the correct return statement here:
return processPayment(resolvedValueArray[0], resolvedValueArray[1])
})

Still, I was wondering, and it should pass the same values, no? Why didn’t it work?

Why resolved Value of the first promise is being passed as the argument of the second promise in .then() method while returning the second promise.
firstPromiseFunction()
.then((firstResolveVal) => {
return secondPromiseFunction(firstResolveVal);
})
.then((secondResolveVal) => {
console.log(secondResolveVal);
});

If you have a look at the functions in library.js you’ll see what is being returned at each point.

For the first one, we’re seeing if the items are in stock. If yes (resolved), we’re logging a message, and resolving the promise by producing the order and total as an array. We return that and pass it into the next function.

The next one looks at the order and the total, and attempts to process the payment, by seeing whether the balance of the gift card is higher than the total, then resolving with the order and a tracking number.

Which is passed into the shipOrder function,which tells you the tracking number.

So it’s a chain of events where the outcome of one function is needed for the next function to run.

Does that make sense?

3 Likes

I know there are lot a questions on hold but i would liek to understand

checkInventory(order)
.then((resolvedValueArray) => {
  return processPayment(resolvedValueArray)
  // Write the correct return statement here:
 
})
.then((resolvedValueArray) => {
  // Write the correct return statement here:
  return shipOrder(resolvedValueArray);
})
.then((successMessage) => {
  console.log(successMessage);
})
.catch((errorMessage) => {
  console.log(errorMessage);
});

How come the console.log(successMEssage) will be linked to the ‘true’ output and the success handling events ? same for the fail. Because i can’t see where are the links between the checkInventory outcome of the logicals and the resolved/fail events to get this console.log …

Thanks.

I am trying to understand the entirety of Chaining Multiple Promises topic, but looking at it and trying to understanding fully what is taking place within the files (library.js and apps.js) is extremely confusing. Makes me question whether I am up to the task with this. Anyone have any advice or tips on how to understand what is going on with this section?

1 Like

Thanks for the help.Gotcha <3

1 Like

where is the .then (rejection) function in the example to the Left??? is it not needed?

1 Like

Did you found an answer to this?
My best regards,

can anyone please explain whats happening here!!

const shipOrder = (responseArray) => {

const order = responseArray[0];

const trackingNum = responseArray[1];

am really confused!!

I’m learning too and I could be wrong. Someone please verify this.

In library,js, both processPayment and shipOrder have responseArray as parameters.

The resulting promise from checkInventory will be passed into then() as resolvedValueArray and then into then()'s callback function processPayment as the argument for responseArray .

processPayment will then return a promise that is passed into the next then() in the chain as resolvedValueArray, which passes it into the callback function shipOrder as the argument for responseArray.

Promises are extremely confusing :dizzy_face: :exploding_head:, i don’t understand what is going on in any lessons, can someone please share any other easy resources to understand promises ?

Guys, I have a question regarding this code:

const store = {

sunglasses: {

inventory: 817, 

cost: 9.99

},

pants: {

inventory: 236, 

cost: 7.99

},

bags: {

inventory: 17, 

cost: 12.99

}

};

const checkInventory = (order) => {

return new Promise ((resolve, reject) => {

setTimeout(()=> {

const itemsArr = order.items;

let inStock = itemsArr.every(item => store[item[0]].inventory >= item[1]);

if (inStock){

 let total = 0;   

 itemsArr.forEach(item => {

   total += item[1] * store[item[0]].cost

 });

 console.log(`All of the items are in stock. The total cost of the order is ${total}.`);

 resolve([order, total]);

} else {

 reject(`The order could not be completed because some items are sold out.`);

}

}, generateRandomDelay());

});

};

const processPayment = (responseArray) => {

const order = responseArray[0];

const total = responseArray[1];

return new Promise ((resolve, reject) => {

setTimeout(()=> {

let hasEnoughMoney = order.giftcardBalance >= total;

// For simplicity we’ve omited a lot of functionality

// If we were making more realistic code, we would want to update the giftcardBalance and the inventory

if (hasEnoughMoney) {

 console.log(`Payment processed with giftcard. Generating shipping label.`);

 let trackingNum = generateTrackingNumber();

 resolve([order, trackingNum]);

} else {

 reject(`Cannot process order: giftcard balance was insufficient.`);

}

}, generateRandomDelay());

});

};

const shipOrder = (responseArray) => {

const order = responseArray[0];

const trackingNum = responseArray[1];

return new Promise ((resolve, reject) => {

setTimeout(()=> {

 resolve(`The order has been shipped. The tracking number is: ${trackingNum}.`);

}, generateRandomDelay());

});

};

// This function generates a random number to serve as a “tracking number” on the shipping label. In real life this wouldn’t be a random number

function generateTrackingNumber() {

return Math.floor(Math.random() * 1000000);

}

// This function generates a random number to serve as delay in a setTimeout() since real asynchrnous operations take variable amounts of time

function generateRandomDelay() {

return Math.floor(Math.random() * 2000);

}

module.exports = {checkInventory, processPayment, shipOrder};

My Question:
What is happening here resolve([order, total]); in checkInventory function?

i think ‘order’ that we passing in is a nested list.

order= [[suglasses,2], [pants,1]]

so each item here is a list/array i.e [suglasses,2] and item[0] = sunglassses