FAQ: JavaScript Promises - The onFulfilled and onRejected Functions

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' ?
4 Likes

3 posts were split to a new topic: How does the inventory comparison function work?

4 posts were merged into an existing topic: How does the inventory comparison function work?

2 posts were split to a new topic: What caused my reference error?

3 posts were split to a new topic: How does .then know what to pass?

2 posts were split to a new topic: What is the difference between quotes and backticks?

3 posts were split to a new topic: What is my error?

3 posts were merged into an existing topic: How does .then know what to pass?

3 posts were merged into an existing topic: How does the inventory comparison function work?

A post was merged into an existing topic: How does .then know what to pass?

Ok, this is a really dumb question, but I seem to run into the same issue a lot, the way I am thinking about this, so if anyone could help, that would be great.

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);

What I want to know is, why does the program know that the resolvedReason or rejectReason points to checkInventory(order)? How does the program know these are connected?

5 Likes

I have two questions relative to this lesson:

  1. Per the lesson instructions, I wrote the following two functions:
    function handleSuccess (resolved) {
    console.log(resolved)
    }
    function handleFailure (rejection) {
    console.log(rejection)
    }
    No where are “resolved” or “rejection” defined anywhere else. I simply made up those labels, yet the code works. How does this mechanism tie those arbitrary names I made up to the checkInventory() function?

  2. Within the checkInventory() function is the following line:
    let inStock = order.every(item => inventory[item[0]] >= item[1]);
    The variable “item” is not defined anywhere else in the code. It’s only appearance within this program is on that line within the setTimeout function. Why doe the program recognize “item”? Where is it declared or defined?

Subsequent edit: Almost immediately after submitting my questions, I think I had an epiphany regarding my second question. The object “item” is not a variable, but a function, using VERY truncated arrow syntax, and returns either “true” or “false” depending upon the resolution of the comparison the occurs to the right of the “=>”. Is this right?

2 Likes

It is declared in the formal parameter; as we see. .every() takes a function that executes on every ‘item’ in the ‘order’ object.

1 Like

Thanks!

Do you have an insight on my first question?

The name we give a parameter has no influence upon the argument. In this case we’re looking at ‘true’ and ‘not true’ as potential arguments. How we come to those is more the question for one to explore. The code given is not enough to help with this investigation so we’ll need to find some literature.

@mtf

I think it must have something to do with the in-built .then() function, which is a method that we call on the promise returned from the checkInventory function. When invoked, .then() must read the state of the promise and pick up either the resolve() or reject() value, depending on the outcome of checkInventory’s if statement. It must then pass this value into either its first (if resolved) or second (if rejected) callback function, where it ends up as the single parameter which you have arbitrarily named as either resolved or rejection .

1 Like

@mtf @midlindner

In this exercise the function checkInventory is exported from one file, and imported into another, using the following code:

module.exports = { checkInventory };

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

I’m not sure why the function name checkInventory is wrapped in curly braces.

In the lesson Intermediate Javascript Modules, we learnt in Exercise 2. module.exports and Exercise 3. require( ) that the name of the module being exported/imported is written with a capital letter and without curly braces. Then in Exercise 4. module.exports II we learnt that we do use curly braces in  module.exports = { };  when we directly assign the data and functions (which we’re exporting) to module.exports  as properties of an object which we create with the curly braces — instead of exporting them by reference to a previously defined module name. However, I do realise that neither of these situations really matches the one we have in this exercise where we are exporting a single, pre-defined function by reference to its function name.

Are the curly braces actually necessary? The function is successfully exported/imported, and everything seems to work just as well, when I run the same code but without the curly braces.

In later exercises in the Intermediate Javascript Modules lesson, we learnt that we do wrap the variable names of the data we are exporting/importing in curly braces when these are separately named exports. At first, this would seem to explain why we use curly braces to export/import the function in this exercise; however, in the modules lesson, the curly braces are used in this way when we are exporting/importing using ES6 syntax, which is different from the Node.js syntax we are using here.

In this exercise, are the curly braces used with module.exports because we are exporting a single function, rather than a pre-defined module? That would seem strange to me because modules seem to be defined in exactly the same way as objects (only with a name that starts with a capital letter) and, after all, functions are also objects.

Do we only start the name/identifier with a capital letter when exporting the whole file as a pre-defined module? Can this pre-defined module only be an object literal i.e. not a function? Is that why we don’t use a capital letter when exporting/importing the function in this exercise? Even if there was only one function in the file, and we exported that, would we still not use a capital letter for this same reason?

All in all, I’m still struggling to understand what’s actually going on here in terms of the curly braces and capital letters. Could someone shed some light on this?

JavaScript modules - JavaScript | MDN

Can’t find a definitive syntax rule with regard to curly braces, only that multiple items can be exported or imported using a comma separated list within. Still digging…

The capital letters refer to classes, which can also be modules.

There are four links at the bottom of the above article. One expects more is revealed in those articles.


One thought that occurs to me is scoping. It could be what the curly braces are for… Block scope, of a sort.

This puts these functions and variables into a module scope. The module scope can be used to share variables between the functions in the module.

But unlike function scopes, module scopes have a way of making their variables available to other modules as well. They can say explicitly which of the variables, classes, or functions in the module should be available.

ES modules: A cartoon deep-dive


import - JavaScript | MDN

Scroll down to Syntax and you will see that single names can be written without curly braces, as quoted values.

module is the current module.
exports is an object within the current module.

module.exports = { var1 } // You are assigning a object with the item var1 to the exports object
module.exports = var1 // You are assigning var1 to the exports object

Both work.

Proof:
If you go to library.js, and type:
console.log(module.exports);
And in bash you type
node library.js // { checkInventory: [Function: checkInventory] }

You will get the same without squiggly brackets if you remove the ‘object squiggly brackets’

@mtf

Yes, I can see now that using the curly braces places the function checkInventory within an object as a key/value pair, and it is this object that we are then exporting.

When the curly braces are removed, what we are exporting is just the function, as follows:

module.exports = checkInventory;
console.log(module.exports);

// => [Function: checkInventory] i.e. not a property (key/value pair) of an object 

I assume that this is what you meant.

When importing a single function using Node.js notation… e.g.

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

… wrapping the variable name in curly braces when declaring it with const  looked strange to me. When declaring a variable, the only other time I’d seen the variable name wrapped in curly braces like this, is when assigning an object property (i.e. a key/value pair) to a separate variable using destructured assignment.
So, I think that if we…
(i) assign one or more pieces of data to an object as key/value pairs by wrapping their variable names (separated by commas) in curly braces, and then…
(ii) export this object to another file…
… on importing this object, if we use the above code to assign its key/value pairs to separate variables again, we must be doing it using destructured assignment. Do you agree?

To be able to export/import more than one separate piece of data, I can see that we have to use curly braces to assign all of them to a single object as its properties on export, and also to then assign each property to a separate variable again on importing. However, if we are only exporting one piece of data from our file (such as with the  checkInventory  function in our example), then I don’t think we need to use curly braces in either the export or import statement, because we can just (i) export the data as a single variable without having to first assign it to an object, and then (ii) reassign the data directly to a variable in the file we are importing to, without having to use destructured assignment; although, I can also see that there is nothing stopping us from assigning just one piece of data to an object by wrapping it in curly braces in the export statement, but if we then don’t use curly braces in the import statement as well, we would have to access the data as a property of an object by using dot notation, rather than being able to access it directly via a single variable name e.g.

// export file
const data = 'myData';
module.exports = {data};

// import file
const data = require('./file.js');

console.log(data);           // => {data: [Function: data]}
console.log(data.data);      // =>        [Function: data]

Even though the lesson Intermediate Javascript Modules only covers exporting/importing separately named exports with ES6 notation, as follows…

// export file
export {identifier1, identifier2, identifier3 ... };

// import file
import {identifier1, identifier2, identifier3 ... } from './file'; 

… after what I’ve now found out, I’m going to assume that we can do the same thing, and wrap our variable names in curly braces, with Node.js notation, as follows…

// export file
module.exports = {identifier1, identifier2, identifier3 ... };

// import file
const {identifier1, identifier2, identifier3 ... } = require('./file.js'); 
2 Likes