I have a React Redux app that needs to call multiple API endpoints using axios
, await the results from these API calls, then dispatch an action.
Problem: In my current implementation below, it appears that the action is being dispatched by redux-thunk
before the API call results are returned by axios
.
How can we fix the problem so that we wait for all 3 results to be returned from the 3 axios
calls, before dispatching the action?
/src/actions/index.js
const axios = require('axios');
import { GET_PRICES } from './types';
export function getSpotPrice(crypto) {
axios.get(`https://api.coinbase.com/v2/prices/${crypto}-USD/spot`).then( (response) => {
return parseFloat(response.data.data.amount);
}).catch((err) => {
console.log(err)
})
}
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function getSpotPrices() {
return function(dispatch) {
const cryptoList = ['BTC', 'ETH', 'XRP'];
let cryptoRates = {}
cryptoList.forEach(async (crypto, i) => {
await timeout(1000); // Wait 1 sec between API calls
cryptoRates[crypto] = await getSpotPrice(crypto);
});
dispatch({
type: GET_PRICES,
payload: cryptoRates,
})
console.log('cryptoRates:', cryptoRates) // returns {}
}
}
You need to make the containing function async await all of your async calls before dispatching, like so:
export function getSpotPrices() {
return async function(dispatch) {
const cryptoList = ['BTC', 'ETH', 'XRP'];
let cryptoRates = {}
for(let crypto of cryptoList) {
await timeout(1000); // Wait 1 sec between API calls
cryptoRates[crypto] = await getSpotPrice(crypto);
}
dispatch({
type: GET_PRICES,
payload: cryptoRates,
});
console.log('cryptoRates:', cryptoRates);
}
}
Another way I believe you can do this is with the Promise.all method. When all the promises in an array have resolved, it's then statement is called.
var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.