FAQ: JavaScript Promises - The onFulfilled and onRejected Functions


#1

This community-built FAQ covers the “The onFulfilled and onRejected Functions” exercise from the lesson “JavaScript Promises”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Asynchronous JavaScript
Asynchronous JavaScript

FAQs on the exercise The onFulfilled and onRejected Functions

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!


#3

I can’t type anything in the terminal! (Which is required for step 5.)


#4
app.js
const {checkInventory} = require('./library.js');

const order = [['sunglasses', 1], ['bags', 2]];

// Write your code below:
const handleSuccess = (resolvedValue) => {
    console.log(resolvedValue);
};

const handleFailure = (rejectReason) => {
    console.log(rejectReason);
};

checkInventory(order)
    .then(handleSuccess, handleFailure);
library.js
const inventory = {
    sunglasses: 1900,
    pants: 1088,
    bags: 1344
};

const checkInventory = (order) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let inStock = order.every(item => inventory[item[0]] >= item[1]);
            if (inStock) {
                resolve(`Thank you. Your order was successful.`);
            } else {
                reject(`We're sorry. Your order could not be completed because some items are sold out.`);
            }
        }, 1000);
    })
};

module.exports = { checkInventory };```

> why  in this(let inStock = order.every(item => inventory[item[0]] >= item[1]);)do you append 'inventory' ?

#5

const checkInventory = (order) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
let inStock = order.every(item => inventory[item[0]] >= item[1]);
if (inStock) {
resolve(Thank you. Your order was successful.);
} else {
reject(We're sorry. Your order could not be completed because some items are sold out.);
}
}, 1000);
});
};


I couldn’t figure out what’s going up there.

  1. first, what’s the use of this expression ‘inventory[item[0]] >= item[1])’. This seems like an array but ‘inventory’ is an object.
  2. what kind of function declaration is this? Is this a loop?
  3. And what’s the use of a success handler and a failure handler if all they do is; to log or return resolve() a reject(). This can be even accomplished by passing the executer function into the promise.

#6

As you can see checkInventory is a function which takes order as an argument. See in file app.js that we are actually passing an array of array to this function. order.every is used to apply a function on every value of that particular object which in this case is an array.
Inside order.every number of a particular item of the inventory is compared with the demanded value. If every asked item is sufficient in quantity then the promise is resolved otherwise rejected.


#7

(item => inventory[item[0]] >= item[1]);

this method comparing if both arrays match . can some one explain in details please/how ?

what value is taking this index here? > [item[0]] / number of items in inventory ? if so, how they compare match of names ?


#8

I’m also confused by

setTimeout(() => {
let inStock = order.every(item => inventory[item[0]] >= item[1]);

I understand it’s looking at the array in app.js, but why is it specifying “inventory” when “inventory” is an object in library.js? And the inventory object does not contain an array, so I don’t understand why it is referring to one after pointing towards the inventory object.

Could someone also clarify why this is being called inside a setTimeout? I think the point is to push it to the bottom of the code but I’m not sure exactly why we are doing this.

Thanks!


#9

When i try and run the program in the terminal it comes up with this :
(node:316) UnhandledPromiseRejectionWarning: Un
handled promise rejection (rejection id: 1): Re
ferenceError: resolveValue is not defined
(node:316) DeprecationWarning: Unhandled promis
e rejections are deprecated. In the future, pro
mise rejections that are not handled will termi
nate the Node.js process with a non-zero exit c
ode.

Can someone tell me how to stop this.


#10

In the example for this exercise, the handleSuccess function takes in a variable and logs it to console. My first question is how does the prom.then function know which handle function to pass through? Since the resolvedValue variable doesn’t explicitly refer to the resolve outcome, how does it know what to log to console?

let prom = new Promise((resolve, reject) => {
let num = Math.random();
if (num < .5 ){
resolve(‘Yay!’);
} else {
reject(‘Ohhh noooo!’);
}
});

const handleSuccess = (resolvedValue) => {
console.log(resolvedValue);
};

const handleFailure = (rejectionReason) => {
console.log(rejectionReason);
};

prom.then(handleSuccess, handleFailure);

My second question is does order matter? If I flip the order of handleSuccess and handleFailure so that it is:
const handleFailure = (rejectionReason) => {
console.log(rejectionReason);
};

const handleSuccess = (resolvedValue) => {
console.log(resolvedValue);
};

prom.then(handleSuccess, handleFailure);
Does the prom.then function still pass the correct handles?


#11

1: first, what’s the use of this expression ‘inventory[item[0]] >= item[1])’. This seems like an array but ‘inventory’ is an object.

You’re right, inventory is an object. We’re using the square bracket notation to access one of its properties.

Here item is an order item like ['sunglasses', 1]: an array with an item name and quantity. So item[0] is the name of an inventory item like “sunglasses.”

That means in inventory[item[0]], we are doing something like inventory['sunglasses'] - accessing inventory's sunglasses property, the value of which would be the amount of sunglasses in stock.

So we are making sure the item quantity in stock (inventory[item[0]]) is at least equal to the quantity on the order (item[1])).

2: what kind of function declaration is this? Is this a loop?

No, not a loop but rather arrow functions.

You could rewrite that code segment like this without arrow functions:

function checkItemInStock(item) {
  return inventory[item[0]] >= item[1];
}

function checkAllItemsInStock(resolve, reject) {
  let inStock = order.every(checkItemInStock);
  if (inStock) {
      resolve("Thank you. Your order was successful.");
  } else {
      reject("We're sorry. Your order could not be completed because some items are sold out.");
  }
}

function executePromise(resolve, reject) {
  setTimeout(checkAllItemsInStock(resolve, reject), 1000);
}

function checkInventory(order) {
  return new Promise(executePromise);
}

3: And what’s the use of a success handler and a failure handler if all they do is; to log or return resolve() a reject().

I think the practical benefit of the handlers would be if they’re doing something more complex than logging.

The other benefit is that checkInventory stays focused on just checking inventory, and doesn’t worry about logging to the console or anything else.


#12

The full line of code you’re looking at is:

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

Here it is broken down a bit:

  • order: an array of order items
  • item: an order item
  • inventory[item[0]] >= item[1]: whether an item is in stock
  • order.every(...);: returns whether all order items are in stock

item here is an order item. All the order items are arrays with 2 elements: (1) item name, (2) quantity ordered. (Example item: ['sunglasses', 1].)

inventory is an object whose properties are inventory item names, and the values are how many of each item is in stock. (Example property: sunglasses: 1000.)

Keeping that example item and property in mind, you could “translate” your code segment like this:

item => inventory[item[0]] >= item[1] //Original code
['sunglasses', 1] => inventory[item[0]] >= item[1] //Replaced item
['sunglasses', 1] => inventory['sunglasses'] >= 1 //Replaced item[0] and item[1]
['sunglasses', 1] => 1000 >= 1 //Replaced inventory[item[0]]
['sunglasses', 1] => true //"Translated" code

So for order item ['sunglasses', 1], whether it is in stock is true (because we have 1000 sunglasses in stock and we only ordered 1).

If this is true for all the order items, then order.every(...) will return true, making inStock also true.


If it makes things clearer, you could take that entire line:

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

and rewrite it like this instead:

let inStock = (() => {
    //Check whether all items on the order are in stock in our inventory.
    for (let i = 0; i < order.length; ++i) { 
        //Get order item.
        const item = order[i];

        //Get the name of the order item.
        const itemName = item[0];

        //Get the quantity we have in inventory of that item.
        const quantityInStock = inventory[itemName];

        //Get the quantity ordered of that item.
        const quantityOnOrder = item[1];

        //Make sure we have enough of that item in stock.
        const itemInStock = quantityInStock >= quantityOnOrder;

        //If this particular item isn't in stock, stop checking and return false.
        if (!itemInStock) { return false; }
        
        //Otherwise, continue the loop and make sure the next order item is in stock.
    }

    //If we made it here, that means all the order items were in stock.
    return true;
})();

#13

It looks like this is the main error: ReferenceError: resolveValue is not defined

I’m thinking you have a typo. My guess is that your handleSuccess function looks something like this:

function handleSuccess(resolvedValue) { //"resolved" with a "d"
  console.log(resolveValue); //"resolve" WITHOUT a "d" - typo
}

It should work if you use resolvedValue everywhere.


#14

Hi,

I am just curious why the following part:

if (inStock) {
resolve(Thank you. Your order was successful.);
} else {
reject(We're sorry. Your order could not be completed because some items are sold out.);

uses the floatation marks under the escape button (it won’t post them in this post I have noticed) instead of ‘’ or " " ? Thanks for the help!


#15

Did anyone reply to this question yet? I also wonder how the .then() method knows which handle to use for resolve/reject. I swapped them in the syntax but the result remains the same so somehow the method knows which one is which not just by the order they appear in, I just don’t get how.


#16

Do you mean the backtick marks? (``)

I don’t think there is any particular reason they were used here. Using regular quotation marks would work just as well.

One thing you can use backticks for, though, is to create template literals.


By the way, the reason the backticks aren’t showing up in your post is because they are used for special formatting on these forums. If you notice, your “Thank you” and “We’re sorry” messages are in a special font. That’s because surrounding text with backticks treats the text as code.


#17

It actually is just based off the order of the arguments. :slight_smile: The first function you pass in will always be used for resolve, the second for reject.

It is a bit confusing in the example, because even if you do swap the arguments, the result is the same. But that’s just because the success function and failure function do exactly the same thing: take in a message and print it to the console.

You can modify the functions a little to make it easier to see which one is being called, by adding “Success” or “Failure” to the start of the message:

const handleSuccess = (resolvedValue) => {
    console.log(`Success: ${resolvedValue}`);
};

const handleFailure = (rejectReason) => {
    console.log(`Failure: ${rejectReason}`);
};

Then, you can try swapping them around in the .then(). You should see the first function you pass to then() is always used as the resolve function, even if it says “failure,” and vice versa.