re-fire the same asyncAction that failed
Hi, First of all, Thank you for this great package!
Now, My problem is: I need to re-fire the same asyncAction that failed (with the same payload, after changing the local storage accessToken value). How can i do it with out adding it as a metaData to each action?
*userFireAccessToken is just a selector for the refreshed token.
export const onUnauthorizedResponse = (action$, state$) =>
action$.pipe(
switchMap(({type, payload}) => {
if (type.endsWith('ASYNC_FAILURE') && payload?.response?.status === 401) {
if(userFireAccessToken(state$.value) && localStorage.getItem('accessToken') !== userFireAccessToken(state$.value)){
localStorage.setItem('accessToken', userFireAccessToken(state$.value));
return [
/// HERE I WANT TO REFIRE THE LAST ACTION (THE ONE THAT FAILD) WITH THE SAME PAYLOAD
];
}
}
return [];
}),
);
Word of advice - wrap you code example in triple backticks
```javascript your code here ```
Will this work?
export const onUnauthorizedResponse = (action$, state$) =>
action$.pipe(
switchMap(action => {
// don't destruct immediately, get the full action, and return it later?
const {type, payload} = action
if (type.endsWith('ASYNC_FAILURE') && payload?.response?.status === 401) {
if(userFireAccessToken(state$.value) && localStorage.getItem('accessToken') !== userFireAccessToken(state$.value)){
localStorage.setItem('accessToken', userFireAccessToken(state$.value));
return [action];
}
}
return [];
}),
);
No... you are trying to fire an action of type ASYNC_FAILURE with its payload. I want to fire the action how fires this failure, The ASYNC_REQUEST.
Here is my solution for this problem. Hope it will be helpful for some other visitors from the future.
Epic
export const onSaveLastAsyncRequest = (action$) =>
action$.pipe(
switchMap((action) => {
if (action.type.endsWith('ASYNC_REQUEST')) {
return [saveLastAsyncRequest({actionToFire: action})];
}
return [];
}),
);
Epic
export const onUnauthorizedResponse = (action$, state$) =>
action$.pipe(
tap(async ({type, payload}) => {
if (type.endsWith('ASYNC_FAILURE') && payload?.response?.status === 401) {
const user = await firebase.auth().currentUser;
const userToken = await user?.getIdToken();
await localStorage.setItem('accessToken', userToken || accessToken());
}
}),
switchMap(({type, payload}) => {
if (type.endsWith('ASYNC_FAILURE') && payload?.response?.status === 401) {
return [state$.value.lastAsyncRequest?.actionToFire];
}
return [];
}),
);
Action
export const saveLastAsyncRequest = makeActionCreator('SAVE_LAST_ASYNC_REQUEST_TO_STATE');
Reducer
export const lastAsyncRequest = (state= null, action)=> {
switch (action.type) {
case actions.saveLastAsyncRequest.TYPE:
return {
...action.payload,
};
default:
return state;
}
};