Reputation: 3767
I have an effect that may or may not dispatch an action:
handleMainAccount$ = createEffect(() => {
return this._actions$.pipe(
ofType(setUserDetails),
tap( (details) => {
if (details?.mainAccount) {
const fakeData = { foo: 'bar'};
this._accountHttpSvc.updateAccount(fakeData).pipe(
take(1), // so we don't have to unsub
map((res) => {
this._userStore.dispatch(setMainAccount({fakeData}));
}),
).subscribe();
}
// else
// we are not dispatching any action
})
);
} , { dispatch: false } ); // setting as false, because we may or may not dispatch an action
I have dispatch as false, because some times this effect may not dispatch an action. Is this bad practice? What would be the negative impact if any?
Upvotes: 3
Views: 3794
Reputation: 562
Imho it's a bad practice. I divide effects in 2 categories:
Yours is kinda "both". It becomes more difficult to test and manage if requirements should change.
Also you're subscribing manually inside your effect: that's a bad practice, too! With this code, you don't have the level of control you'd have with flattening operators (eg. cancelling the previous request).
As a general guide, suppose you have this situation:
map(action => condition ? otherAction : null)
This obviously doesn't work because null
is not a valid action.
So, change map
to switchMap
(or another flattening operator) and modify your code this way:
import { switchMap, of, EMPTY } from 'rxjs';
...
switchMap(action => condition ? of(otherAction) : EMPTY)
In your scenario you want to perform a request conditionally. It'd be something like this instead of your tap
:
switchMap(condition => {
if (!condition) {
return EMPTY
}
return this.service.update(...).pipe(
take(1),
map(x => yourAction())
)
})
Obviously you can use any other flattening operator instead of switchMap
. With switchMap
a concurrent request would cancel the previous one, with mergeMap
they'd be handled in parallel, with concatMap
they'd be queued, with exhaustMap
the second one would have no effect if the previous call hasn't finished.
Upvotes: 5