Jake Dluhy Jake Dluhy - 1 month ago 18
Javascript Question

Using rxjs sample within redux-observable to listen to other actions

I'm using redux-observable to act as the middleware between dispatching actions and the store. I'm trying to use the rxjs

sample
function to accomplish this, but unfortunately it's not working for me. Here's my epic:

export const inviteUserEpic = (action$) => {
return action$.ofType(a.INVITE_USER)
.flatMap(({ body }) => {
return Observable.concat(
Observable.of({ type: authActions.REGISTER_REQ, body }),
Observable.of(push(`/team/${body.teamId}`))
.sample(action$.ofType(authActions.REGISTER_SUCCESS))
);
});
};


Basically the idea is that there are multiple places to register a new user, and in this case I want to redirect to the team page after I successfully register the user. I'm seeing REGISTER_REQ emit, and it will subsequently emit REGISTER_SUCCESS. But the redirect observable is never sampled.

Answer

This is because the sample operator is only active and subscribing to the notifier when the source itself is still active. In this case, the source is an Observable.of() that will emit the provided action and then immediately complete(), meaning you will no longer be sampling anything--it's already complete() before your REGISTER_SUCCESS action is dispatched. i.e. .sample() does not prevent an observable chain from completing.

Instead, you'll want to start by matching the expected action, and then when matched map that to your push()

action$.ofType(authActions.REGISTER_SUCCESS)
  .map(() => push(`/team/${body.teamId}`))

Putting that together with your existing Epic

export const inviteUserEpic = (action$) => {
    return action$.ofType(a.INVITE_USER)
    .flatMap(({ body }) => {
        return Observable.concat(
            Observable.of({ type: authActions.REGISTER_REQ, body }),
            action$.ofType(authActions.REGISTER_SUCCESS)
              .take(1)
              .map(() => push(`/team/${body.teamId}`))
        );
    });
};

You can see a working example of this here: http://jsbin.com/sonuqob/edit?js,output