Reputation: 1494
I am working on a React Redux app. I have an action in which I am calling a utility function before dispatching the action.
import GetDataFromAPIs from "../utils/menu-creator";
export const UPDATE_DATA = 'UPDATE_DATA';
export const updateData = () => {
const newData = GetDataFromAPIs();
return{
type: UPDATE_DATA,
payload: newData
};
};
And, here is what GetDataFromAPIs.js is loosely doing:
import React from "react";
import axios from "axios";
const apiOneData = axios.get('/api/a');
const apiTwoData = axios.get('/api/b');
const GetDataFromAPIs = () => {
axios.all([apiOneData, apiTwoData]).then(axios.spread((...responses) => {
var firstDataSet = responses[0].data
var secondDataSet = responses[1].data;
var dataObject = [];
dataObject.push(firstDataSet);
dataObject.push(secondDataSet);
return dataObject;
})).catch(errors => {
console.log("There was an error.");
})
}
export default GetDataFromAPIs;
But when the application runs newData is set as undefined. I am trying to step through GetDataFromAPIs.js but it traces till axios.all and then breaks out of the function. I don't see any error in the console.
So what I am guessing is that action is dispatched before the two axios.all is resolved. I thought this would be synchronous (newData will get the data back and then the action will be dispatched). Am I doing this wrong?
Upvotes: 2
Views: 1310
Reputation: 10618
You need to explicitly tell the action to wait
to get that data asynchronously. To do that, make the following changes:
Your GetDataFromAPIs
function should look this this:
const GetDataFromAPIs = async () => {
// everything in here stays the same
}
And your updateData
function should look like this:
export const updateData = async (dispatch) => {
const newData = await GetDataFromAPIs();
return dispatch({
type: UPDATE_DATA,
payload: newData
});
};
dispatch
your action.Note:
If you haven't got redux-thunk
setup then you'll need to install that npm
module and update your createStore
to look something like this:
// other imports
import { applyMiddleware, createStore } from 'redux'
import thunk from 'redux-thunk'
const store = createStore(rootReducer, applyMiddleWare(thunk))
Upvotes: 2
Reputation: 63
GetDataFromApis
doesn't return.
You should do
const GetDataFromApis = async () => {
return axios.all(...
GetDataFromApis
will also return a Promise
so you should await
it in updateData
like so:
export const updateData = async () => {
const newData = await GetDataFromAPIs();
return {
type: UPDATE_DATA,
payload: newData
};
};
Upvotes: 0
Reputation: 5766
I think async/await is what you need.
export const updateData = async () => {
const newData = await GetDataFromAPIs();
return{
type: UPDATE_DATA,
payload: newData
};
};
const GetDataFromAPIs = async () => {
try {
const responses = await axios.all([apiOneData, apiTwoData]).then(axios.spread((...responses);
var firstDataSet = responses[0].data
var secondDataSet = responses[1].data;
var dataObject = [];
dataObject.push(firstDataSet);
dataObject.push(secondDataSet);
return dataObject;
} catch(errors) {
console.log("There was an error.");
})
}
Upvotes: 0