mrks
mrks

Reputation: 5631

Pass value from promise to variable

I tried to return the value from a Promise and assign it to a local variable inside the function, but the Promise gets fired at last.

The function (which will get fired in Vue.js mounted()):

getPriceForYesterday(){
    let yesterdayUSD = [];
    for (let i = 0; i < this.cryptos.length; i++) {
        let cryptoName = this.cryptos[i].title;
        let timestamp = new Date(this.cryptos[i].purchaseDate);
        timestamp.setDate(timestamp.getDate() - 1);
        timestamp = timestamp.toISOString();

        let priceYesterday = getPriceForTimestamp(cryptoName, timestamp);
        Promise.all([priceYesterday]).then((values) => {
            console.log("values", values)
            yesterdayUSD.push(values[0]);
        }).catch(e => console.error(e));

    }
    console.log("yesterdayUSD", yesterdayUSD);
    console.log("yesterdayUSD[0]", yesterdayUSD[0]);
}

Output:

yesterdayUSD []
yesterdayUSD[0] undefined
values [13308.06]
values [1278.69]

I want to use yesterdayUSD to compare it with a local storage value and then return the "result" of the comparison to the vue data.

Upvotes: 2

Views: 5060

Answers (2)

Jeff LaFay
Jeff LaFay

Reputation: 13350

The reason that you're not seeing anything when trying to write out yesterdayUSD is because the promises are executing asynchronously and they're not complete before reaching the lines where you use console.log();

I'm going to assume that you meant to use Promise.All() to wait for all of the promises to complete because that's typically what it is used for. I rewrote your example to populate an array of promises and then wait after they all resolve before writing out the values in yesterdayUSD. That should at least allow you to print out the values after all of the promises complete.

getPriceForYesterday(){
    let yesterdayUSD = [];
    let promises = [];

    for (let i = 0; i < this.cryptos.length; i++) {
        let cryptoName = this.cryptos[i].title;
        let timestamp = new Date(this.cryptos[i].purchaseDate);
        timestamp.setDate(timestamp.getDate() - 1);
        timestamp = timestamp.toISOString();

        let priceYesterday = getPriceForTimestamp(cryptoName, timestamp)
            .then((values) => {
                console.log("values", values)
                yesterdayUSD.push(values[0]);
            })
            .catch(e => console.error(e));

        promises.push(priceYesterday);
    }

    Promise.all(promises).finally(() => {
        console.log("yesterdayUSD", yesterdayUSD);
        console.log("yesterdayUSD[0]", yesterdayUSD[0]);
    });
}

Upvotes: 1

Christian Benseler
Christian Benseler

Reputation: 8065

Maybe you can rewrite this method/function to return a promise, too

getPriceForYesterday(){
    return new Promise( resolve => {
        let yesterdayUSD = [];
        for (let i = 0; i < this.cryptos.length; i++) {
            let cryptoName = this.cryptos[i].title;
            let timestamp = new Date(this.cryptos[i].purchaseDate);
            timestamp.setDate(timestamp.getDate() - 1);
            timestamp = timestamp.toISOString();

            let priceYesterday = getPriceForTimestamp(cryptoName, timestamp);
            Promise.all([priceYesterday])
            .then((values) => {
                yesterdayUSD.push(values[0]);
            })
            .then( () => {
                resolve(yesterdayUSD)
            })

        }
    })
}

and then use it in the mount() method

mount() {
   ...
   getPriceForYesterday().then( yesterdayUSDArray => {
      //do something with this yesterdayUSDArray
   })
}

Upvotes: 2

Related Questions