Raf
Raf

Reputation: 13

Why I can't manipulate returned object from promise inside then?

I have and Promise that return an object and I would like to loop thorough it to sort by prices but I can't manipulate the returned object and I don't know why.

If I just console.log the result like I did on second console.log it shows the values but if I do anything That I founded on the web they return empty array.

This is my code:

getPrices().then(res => {
    console.log(typeof res);
    // console -> object
    console.log('result', res);
    // console -> [] {0: {price: "12.80", competitor: "competitor 1")...} length: 7 __proto__: Array(0)
    console.log('stringfy', JSON.stringify(res));
    // console -> stringfy []
    console.log('array from', Array.from(res));
    // console -> [] length: 0 __proto__: Array(0)
    console.log('object keys', Object.keys(res));
    // console -> [] length: 0 __proto__: Array(0)
});

I also tried using Object.entries and using map direct on res

How is the right way to convert this object to array and use .sort or .map?

And this is my gitPrice function:

export const getPrices = async () => {
    const prices = [];
    data.map(index => {
        request(index.link, (error, response, html) => {
            if (!error && response.statusCode == 200) {
                let che, price, newItem;
                che = cheerio.load(html);
                price = (index.selector.includes("itemprop")) ? che(index.selector).attr('content') : che(index.selector).text();
                newItem = {
                    "price": price,
                    "competitor": index.competitor
                };
                prices.push(newItem);
            } else {
                console.error(`ERROR ${response.statusCode}: Was not possible to scrape the ${index.competitor}: `)
            }
        });
    });
    return prices;
}

Upvotes: 1

Views: 281

Answers (1)

Medet Tleukabiluly
Medet Tleukabiluly

Reputation: 11940

This is common beginner problem, you trying to get array of result, but you should get array of promises, and then resolve them all

export const getPrices = () => {
    const prices = [];
    const dataPromises = data.map(index => { // this contains array of promises
        return new Promise((resolve, reject) => {
          request(index.link, (error, response, html) => {
            if (!error && response.statusCode == 200) {
                let che, price, newItem;
                che = cheerio.load(html);
                price = (index.selector.includes("itemprop")) ? che(index.selector).attr('content') : che(index.selector).text();
                newItem = {
                    "price": price,
                    "competitor": index.competitor
                };
                resolve(newItem); // resolve the value
            } else {
                reject(new Error(`ERROR ${response.statusCode}: Was not possible to scrape the ${index.competitor}: `))
            }
          });
       })
    });
    return Promise.all(dataPromises); // resolve all
}

Upvotes: 1

Related Questions