Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: reducer called 2 times when there's a stream associated with it. #4

Open
zgusth opened this issue May 23, 2018 · 0 comments
Open

Comments

@zgusth
Copy link

zgusth commented May 23, 2018

I have a simple reducer that just sets isLoading to true when loadCounter is called and another that set it to false when loadCounterSuccess is called.

void _loadCounter(FrontendState state, Action<LocalStorage> action, FrontendStateBuilder builder) {
  builder.isLoading = true;
}

void _loadCounterSuccess(FrontendState state, Action<Null> action, FrontendStateBuilder builder) {
  builder.isLoading = false;
}

Then I have a stream that listens to the same action as the _loadCounter reducer. It just reads counter from localStorage and call _loadCounterSuccess reducer when it completes.

Observable _loadCounter(Observable<Action<LocalStorage>> stream, MiddlewareApi<AppState, AppStateBuilder, AppActions> api) {
  return stream.flatMap<void>((localStorage) {
    return Observable
        .fromFuture(localStorage.payload.read('counter'))
        .map<int>(
            (value) => value == null ? CounterState().value : int.parse(value))
        .map<void>((value) {
      api.actions.frontend.loadCounterSuccess();
      api.actions.counter.setCounter(value);
    }).handleError(() => api.actions.frontend.loadCounterFailure());
  });
}

The isLoading state should start at false, then go to true when _loadCounter is called, then go to false again when _loadCounterSuccess is called. That's working perfectly. But the stream is calling _loadCounter reducer again when it finishes, setting isLoading to true again and exploding my app 😢

Not sure if this implementation is following this from javascript.

But if it is, then that's what they say:

REMEMBER: Epics run alongside the normal Redux dispatch channel, after the reducers have already received them. When you map an action to another one, you are not preventing the original action from reaching the reducers; that action has already been through them!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant