Reputation: 537
After a user has been authenticated i need to call 2 functions (AsyncStorage.setItem
and setAPIAuthorization
) followed by 2 redux actions (LOAD_USER
and SET_SESSION_USER
). How would I achieve this based off the attempt below? Or should I create redux actions for both functions also?
const loginUserEpic = (action$, state$) =>
action$.pipe(
ofType('LOGIN_USER'),
mergeMap(() =>
from(axios.post(`/auth`, {})).pipe(
mergeMap(response =>
of(
AsyncStorage.setItem('id_token', response.data.token),
setAPIAuthorization(response.data.token),
{
type: 'LOAD_USER'
},
{
type: 'SET_SESSION_USER',
user: response.data.user
}
)
),
catchError(error => console.log(error))
)
)
);
Thanks to Anas below, here is the update that I am using to achieve what i want. Successful so far. After I store the id_token
it is included in the header of any subsequent api calls. For this reason I need to ensure that the id_token
is saved before calling LOAD_USER
which is an api call.
const loginUserEpic = (action$, state$) =>
action$.pipe(
ofType('LOGIN_USER'),
mergeMap(() =>
from(axios.post(`/auth`, {})).pipe(
mergeMap(response => {
return new Observable(observer => {
AsyncStorage.setItem('id_token', response.data.token);
setAPIAuthorization(response.data.token);
observer.next(
{
type: 'LOAD_USER'
},
{
type: 'SET_SESSION_USER',
user: response.data.user
}
);
});
}),
catchError(error => console.log(error))
)
)
);
Upvotes: 1
Views: 286
Reputation: 3162
another simple way is to use switchMap
switchMap(() => [
{
type: 'LOAD_USER',
},
{
type: 'SET_SESSION_USER',
user: response.data.user,
}
])
It automatically wrap result into observables as long as it's an array. So you no longer need to of()
it. I use it quite a lot in my project.
Upvotes: 0
Reputation: 5727
Setting the session storage is a side effect. So better to do it in a tap,
Your epic should only return actions as output (actions In, actions Out). If you do it that way, redux will complain that you're not returning plain actions.
I will still create action creator for { type: 'LOAD_USER' }
and { type: 'SET_SESSION_USER'}
just because it's cleaner.
const loginUserEpic = (action$, state$) =>
action$.pipe(
ofType('LOGIN_USER'),
mergeMap(() =>
from(axios.post('/auth', {})).pipe(
tap((response) => {
AsyncStorage.setItem('id_token', response.data.token)
setAPIAuthorization(response.data.token)
}),
mergeMap(response =>
of(
{
type: 'LOAD_USER',
},
{
type: 'SET_SESSION_USER',
user: response.data.user,
}
)
),
catchError(error => console.log(error))
)
)
)
Upvotes: 1