How does the inventory comparison function work?

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 Likes

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.

1 Like

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.

13 Likes

(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 ?

7 Likes

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!

2 Likes

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;
})();
8 Likes

why couldn’t it have just been

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

Shouldn’t that work too or would inventory[item] just be the object property name instead of the value of the object property?

Can someone help me to understand the indexing that is happening on this line?

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

I’m confused about what appears to me to be a mismatch in the index which just my not understanding what is really happening here.

thanks,

josh

The every iterator returns a boolean. It will be true if every item in an array meets the condition.

Above, element 0 is compared to element 1 and cannot be less than else the return will be false. We’re assuming that inventory is made up of smaller arrays with at least two elements each.

There is nothing amiss with the indices.

 > a = [[3,2],[3,3],[3,1]]
<- (3) [Array(2), Array(2), Array(2)]
 > a.every(x => x[0] >= x[1])
<- true
 > b = [[3,4],[3,3],[3,1]]
<- (3) [Array(2), Array(2), Array(2)]
 > b.every(x => x[0] >= x[1])
<- false
2 Likes

thanks that helped a lot!

1 Like

Thank a lot man! This part is super clear and tells everything about the logic!

You can’t use inventory[item] because then you are not gonna get the name of the order for example: bags or sunglasses. Instead you will get something like this ['sunglasses, 2]. But you need JUST NAME to reach the values in the inventory object.

Let’s take for example the first item of the order arrray.

  • inventory [item] => inventory [‘sunglasses’, 2] => probably cause an error, because there is no keys called “sunglasses , 2” in inventory object.

  • inventory [item][0] => inventory [‘sunglasses’, 2][0] => inventory[sunglasses] => it will reach the value of the sunglasses inside inventory object. Therefore, the function can compare 2 values each other.

Hope it helps.

Thank you very much for such a perfect explaination!