Reputation: 107
I am trying to wrap my head around the difference between concat and concatMap when using redux-observable.
In my intuition, I'm thinking that concatMap would work:
- From a FAKE_LOGIN
action, it will be switchMap-ed to emit FAKE_LOGIN_AUTHENTICATING
action.
- Inside a FAKE_LOGIN_AUTHENTICATING
action, it will be concatMap-ed to emit FAKE_LOGIN_SUCCESS
action, after a delay of 2 seconds.
However, the above thinking does not work. I tried all sorts of combinations and finally chanced upon the concat operator and surprisingly it works.
What is the difference between the two?
Below are my codes:
this does not work
action$.pipe(
switchMap(
action => of( { type: 'FAKE_LOGIN_AUTHENTICATING' } ).pipe(
concatMap( thing => {
return of( { type: 'FAKE_LOGIN_SUCCESS', payload: { userId: 'user-a', userData: {} } } ).pipe(
delay( 2000 )
);
} )
)
)
);
But this does
action$.pipe(
switchMap(
action => of( { type: 'FAKE_LOGIN_AUTHENTICATING' } ).pipe(
concat(
of( { type: 'FAKE_LOGIN_SUCCESS', payload: { userId: 'user-a', userData: {} } } ).pipe(
delay( 2000 )
)
)
)
)
);
Upvotes: 6
Views: 6200
Reputation: 96979
I think I don't understand your use-case exactly but the main difference between concatMap
and concat
is that concatMap
accepts as a parameter a function that is invoked for every item from its source and that returns an inner Observable (it maps each item from its source to an Observable). concatMap
then calls its callback only when the previous inner Observables completes.
On the other hand, concat
just accepts a list of Observables and subscribes to them one after another when the previous Observable completes.
So in your case the first example just "maps" FAKE_LOGIN_AUTHENTICATING
to FAKE_LOGIN_SUCCESS
.
In the second example the inner block is equivalent to this:
concat(
of({ type: 'FAKE_LOGIN_AUTHENTICATING' }),
of({ type: 'FAKE_LOGIN_SUCCESS', payload: { userId: 'user-a', userData: {}}}).pipe(
delay(2000),
)
)
So it first subscribes to of({ type: 'FAKE_LOGIN_AUTHENTICATING' })
that emits and completes immediately, then subscribes to of({ type: 'FAKE_LOGIN_SUCCESS'...)
that emits immediately as well and then completes.
Upvotes: 11