Hongbo Miao Hongbo Miao - 3 years ago 68
Javascript Question

How to use redux-observable and promise correctly?

I am using hello.js to sign in.

hello('abc').login()
returns a promise.

It did sign in successfully, because hello.js itself saved the token in the local storage.

However, the code below sometimes does not dispatch the action
SIGN_IN_SUCCEED
.

export const signInEpic = (action$, store) =>
action$
.ofType(SIGN_IN)
.mergeMap(action =>
Observable
.fromPromise(hello('msft').login({ scope }))
.map(response => ({
type: SIGN_IN_SUCCEED,
payload: response.authResponse.access_token
})
)
.catch(error => Observable.of({ type: SIGN_IN_FAILED, payload: error }))
);


UPDATE:
Jay's Pause on Caught Exceptions way helped me find the error. The code above has no issue. What causes the problem is that first I try to save the token to the store after getting
SIGN_IN_SUCCEED
. Then I use the token immediately once the app sign in to fetch something. So when the fetch using token step runs before saving token in the store step, it causes the issue which won't dispatch
SIGN_IN_SUCCEED
.

Answer Source

If I make some assumptions about the things missing in your example (e.g. scope, what hello.js does, etc) it works as expected. Here's an example: https://jsbin.com/rasumo/edit?js,output

There must be something else wrong with your code that isn't included here, unfortunately. How did you confirm it's not dispatching the SIGN_IN_SUCCEED action? Were there any errors in the console? Have you tried enabling "Pause on Caught Exceptions" in your debugger to see if you're maybe silently swallowing an error somewhere that is preventing the action from reaching your reducers?

Another thing to confirm is that the Promise returned by hello('msft').login({ scope }) actually does resolve. You could chain a .then() to confirm this.

Hope this helps!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download