I am trying to create an @Effect()
for my action. When I run action with type AuthenticationUserLoad
I get an error.
ERROR Error: Effect "AuthenticationEffects.getUser$" dispatched an invalid action: [object Object]
Here is my Effect
code
@Effect()
getUser$ = this.actions$.pipe(
ofType(AuthenticationUserActions.AuthenticationUserTypes.AuthenticationUserLoad),
map((action) => {
return this.authService.getUser().pipe(
map((user: User) => new AuthenticationUserActions.AuthenticationUserLoadSuccess({user})),
catchError(error => of(new AuthenticationUserActions.AuthenticationUserLoadFailure({error})))
);
})
);
UPDATE
I changed map
to switchMap
and it works.
@Effect()
getUser$ = this.actions$.pipe(
ofType(AuthenticationUserActions.AuthenticationUserTypes.AuthenticationUserLoad),
switchMap((action) => {
return this.authService.getUser().pipe(
map((user: User) => new AuthenticationUserActions.AuthenticationUserLoadSuccess({user})),
catchError(error => of(new AuthenticationUserActions.AuthenticationUserLoadFailure({error})))
);
})
);
Maybe I dont understand the difference between map and switchMap.
In this example, we use tap to perform the side effect itself, and pass “{dispatch: false}” to the “createEffect” function to indicate it does not need to dispatch anything after the side effect completes.
Getting started. It will add and install the @ngrx/effects library to your package. json and scaffold your AppModule to import the NgRx EffectsModule into your application. With the setup complete, we can start modifying the app to introduce and handle some API calls using Effects.
Effects are long-running services that listen to an observable of every action dispatched from the Store. Effects filter those actions based on the type of action they are interested in. This is done by using an operator. Effects perform tasks, which are synchronous or asynchronous and return a new action.
map
operator maps current value, it doesn't care whether it is an observable or not.
Whereas switchMap
or mergeMap
or concatMap
expect a callback to return an observable value, subscribe to it and emits its values.
Therefore when you call map
you say that current value should be transformed to some other.
map(action => return this.authService.getUser()),
// here the value is an observable stream, but not its emits.
when you call switchMap
you say now I want to subscribe to another stream and emit its values. Because it's switchMap
it also says once the parent stream emits (the same action comes) unsubscribe from current child stream and subscribe again to what a new call of this.authService.getUser()
returns.
switchMap(action => return this.authService.getUser()),
// here the value is an emit from this.authService.getUser() stream.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With