I am trying to use a Redux store to get account information from a server, but the returned object is empty. The code is supposed to get a JWT token from a store, and then the token is supposed to be used to get account into from a server and store it as the global state in the store.
I logged the object using the console, but the "accountInfo" object which is supposed to have all of the information about an account is empty.
My code:
if (localStorage.jwtToken) {
const token = localStorage.jwtToken;
setAuthToken(token);
const decoded = jwt_decode(token);
store.dispatch(setCurrentUser(decoded));
const currentTime = Date.now() / 1000
if (decoded.exp < currentTime) {
store.dispatch(logoutUser());
} else {
store.dispatch(getAccountInfo());
console.log(store.getState());
loggedIn = true;
}
}
export const getAccountInfo = () => {
var accountInfo = {};
const token = localStorage.jwtToken;
setAuthToken(token);
const decoded = jwt_decode(token);
const currentUsername = decoded.name;
fetch(${Globals.API_URL}/account/info/?username=${currentUsername}, { headers: { "x-access-token": token }})
.then((res) => res.json())
.then((data) =>
{
console.log(data);
if(data.message != null)
{
accountInfo = {message: data.message};
} else {
accountInfo = data;
}
})
.catch(error => {
accountInfo = {error: error};
})
return {
type: "GET_ACCOUNT_INFO",
payload: accountInfo
}
}
const initialState = {
accountInfo: {}
};
export const accountReducer = (state = initialState, action) => {
switch (action.type) {
case "GET_ACCOUNT_INFO":
return {
...state,
accountInfo: action.payload
};
default:
return state;
}
}
The object as shown in the console:
Object
account:
accountInfo: {}
[[Prototype]]:
The backend part works fine. How do I make the accountInfo object not return empty?
2
Answers
You’re trying to build async logic into an action creator without using the necessary middleware. See Redux Middleware and Side Effects:
If you want to update your store in response to your request, you need to dispatch after it has settled. That means your
getAccountInfo
will need to dispatch an action, instead of returning an object.The offical Redux middleware for async functions is Redux Thunk Middleware. Once you have that configured, you can accomplish what you’re looking for with that:
You may be dispatching this
getAccountInfo
action to the store, but it doesn’t correctly wait for the fetch logic to complete before trying to use theaccountInfo
object, and it doesn’t again dispatch an action to pass theaccountInfo
value to the store to be handled.I’ll assume you have already setup and configured the Redux store to handle asynchronous actions, e.g. Thunk middleware.
getAccountInfo
should consume adispatch
function that the Thunk middleware will pass it. This allows you to dispatch an action with the populatedaccountInfo
value.accountInfo
payload to the end of the Promise chain, or convert the entire function toasync/await
/try/catch
, the latter of which is more common.