0

I'm developing a script that connects with an API, then with the JSON reponse do some operations and then reformat the JSON to send it to another API.

But now I'm stuck in the first step as I can't deal with the first part as my Promises is not working as expected. How can I store the API's response into a variable? For development puropose I stored one API response into a JSON file. This is my code:

declare var require: any;
let url = './data/big buy/big-bui-product-list.json';
const fs = require('fs'); 

let counter = 0;


const getProductList = () => {
    return new Promise((resolve, reject) => {
        fs.readFile(url, 'utf8', (err, data) => {
            if(err){
                return reject (err);
            }
            else {
                return resolve(JSON.parse(data));
            }
        })
    })
}

const getProductStock = () => {
    return new Promise((resolve, reject) => {
        fs.readFile('./data/big buy/big-bui-product-stock.json', 'utf8', (err, data) => {
            if(err) {
                return reject(err);
            }
            else {
                return resolve(JSON.parse(data));
            }
        })
    })
}


try {
    let products;
    console.log('Products:');
    Promise.all([getProductList()])
                .then(function(result) {
                    products = result[0];
                });    
 
    console.log('Stocks:');
    const productStock = Promise.all([getProductStock()]);
                        
    console.log(products);
    
}
catch(e) {
    console.log((`Ha ocurrido un error: ${e.message}`));
}
finally {
    
}

In this code, what I do is getting a list of products and then get the stocks of all the products, later I will add a new function that will filter by stock and get me just a list of products where stock is bigger than X units. Now when I launch it from the terminal I dont' get the response stored into products variable but if I add .then((data) => console.log(data)) into the Promise I see on screen the JSON but as I dont' have it stored it in any variable I don't see how can I work with the objects I'm retrieving.

jcobo1
  • 1,065
  • 1
  • 18
  • 34

2 Answers2

0

Promises are asynchronous. They are quite literally promises that a value will be yielded in the future. When you do getProductList().then(x => products = x), you're saying that Javascript should fetch the product list in the background, and once it's finished, it should set the products variable to x. The key words there are "in the background", since the code afterwards keeps running while the product list is being fetched. The products variable is only guaranteed to be set after the .then portion is run. So, you can move things into the .then:

try {
    let products;
    getProductList().then(list => {
        products = list;
        return getProductStock(); // leverage promise chaining
    }).then(stocks => {
        console.log("Products:", products);
        console.log("Stocks:", stocks);
    }); 
}
catch(e) {
    console.log((`Ha ocurrido un error: ${e.message}`));
}
finally {
    
}
Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • I just tested what you mentioned and now I get the results on the console in the same order as I execite it, first products and then stocks while before I was gettin it backwards first stocks and later products, but still can't see how store into a variable to work with. If I do a console.log of products variable 'm still getting undefined result. – jcobo1 Nov 22 '20 at 12:57
  • @kiewlovsky Are you trying to `console.log` the variable outside of the `then` callback? – 3limin4t0r Nov 22 '20 at 13:09
  • yes, after the .then I put console.log(products); – jcobo1 Nov 22 '20 at 13:09
0

You seem to be missing some fundamental knowledge about promises. I suggest reading through the MDN Using Promises guide to familiarize yourself a bit with them.

A structure like below never works.

let variable;
promise.then(data => variable = data);
console.log(variable);

This is because it is executed in the following manner.

  1. Create the variable variable.
  2. Add a promise handler to the promise.
  3. Log variable.
  4. Promise gets resolved.
  5. Execute the promise handler.
    1. Set variable variable to data.

If you are using Node.js 10 or higher you can use the promise API of file system to simplify your code quite a bit.

const fs = require('fs/promises');

const readJSON = (path) => fs.readFile(path, "utf8").then((json) => JSON.parse(json));
const getProductList = () => readJSON("./data/big buy/big-bui-product-list.json");
const getProductStock = () => readJSON("./data/big buy/big-bui-product-stock.json");

Promise.all([
  getProductList(),
  getProductStock(),
]).then(([products, stocks]) => {
  console.log({ products, stocks });
}).catch((error) => {
  console.log("Ha ocurrido un error:", error.message);
}).finally(() => {
  // ...
});
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52