Reputation: 349
first of all it is worth mentioning the fact that I still haven't very clear rxjs's operators. I studied them but in the practical act if I either use switchMap, mergeMap or map the result still seems the same.
The code below creates an infinite loop, I tried to place debuggers strategically in order to understand the flow but it must be strictly related to the HTTP response time, hence appears to jump between the effects in a very random way.
@Effect()
addNewDocument = this.actions$.pipe(
ofType(UserActions.ADD_DOCUMENT),
map((action: UserActions.AddNewDocument) => {
return action.document;
}),
switchMap((document: FormData) => {
return this.store.select('user').pipe(
map((user) => {
return {
document,
uuid: user.uuid
};
})
);
}),
switchMap((payload: { document: FormData, uuid: string }) => {
return this.httpClient.post(
`${environment.apiUrl}user/${payload.uuid}/documents`,
payload.document
).pipe(
mergeMap((response: any) => {
return [
{
type: UserActions.ADDED_DOCUMENT,
response
}
];
}),
catchError((error) => of(new AppActions.GenericError(error)))
);
})
);
@Effect({dispatch: false})
addedNewDocument = this.actions$.pipe(
ofType(UserActions.ADDED_DOCUMENT),
tap(() => {
this.router.navigate(['/user/documents']);
})
);
My intent is:
I'd really appreciate if you help me to understand what's wrong. If you think I missused some operators or you know a better method to use them, please let me know.
Thank you in advance.
Upvotes: 2
Views: 1381
Reputation: 5602
It appears that your user
state is changing in your application which is causing the looping in the effect. Try using take(1)
while taking user
state in effect like this:
switchMap((document: FormData) => {
return this.store.select('user').pipe(
take(1),
map((user) => {
return {
document,
uuid: user.uuid
};
})
);
})
take(1)
will complete the observable and will tear down the action until the next UserActions.ADD_DOCUMENT
action dispatched.
Hope it helps.
Upvotes: 1