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

Waiting for multiple async calls in Flutter Redux? #65

Closed
hash404 opened this issue Jul 27, 2018 · 7 comments
Closed

Waiting for multiple async calls in Flutter Redux? #65

hash404 opened this issue Jul 27, 2018 · 7 comments

Comments

@hash404
Copy link

hash404 commented Jul 27, 2018

I'm encountering the same issue at reduxjs/redux#723 where I need to wait for 3 or 4 async calls in Redux before another action.

In Redux, with Redux Thunk, you can do something like this (from the answer):

Promise.all([
  store.dispatch(doSomething()),
  store.dispatch(doSomethingElse())
]).then(() => {
  console.log('I did everything!');
});

Is there a equivalent in Flutter Redux? I have multiple actions which I to be finished before I continue. I don't think Flutter Redux Thunk returns a Future which prevents me from using the same pattern in the solution from reduxjs/redux#723.

@brianegan
Copy link
Owner

Hey there -- Yah, we need to fix dispatch so it returns the action from the dispatch call. Please see fluttercommunity/redux.dart#26.

In the meantime, you can do something like this:

final resultA = doSomething();
final resultB = doSomethingElse();

store.dispatch(resultA);
store.dispatch(resultB);

Future.wait([
  resultA,
  resultB,
]).then(() => {
  console.log('I did everything!');
});

@brianegan
Copy link
Owner

Heya @hash404 -- did this help out?

@hash404
Copy link
Author

hash404 commented Aug 15, 2018

Sorry for the late response, I'm still trying to figure out the implementation details for the Dart way to do this.

function doSomething() {
  return dispatch => 
    fetch(
      '/api/something'
    ).then(
      response => response.json()
    ).then(
      json => dispatch({ type: DO_SOMETHING, json }),
      err => dispatch({ type: SOMETHING_FAILED, err })
    );
}

In reduxjs/redux#723, they have doSomething() return a promise when calling store.dispatch(doSomething()) (thanks to the Redux Thunk middleware).

Does this still carry over to Flutter with the Redux Thunk middleware?

@brianegan
Copy link
Owner

Hey there -- it won't quite be the same until we fix up fluttercommunity/redux.dart#26. Fixing that would allow dispatch to return the action that's been passed in (in this case, the Future you'd return from doSomething). Therefore, it currently requires a bit more coordination.

Since that chance would require we bump the major version and creates quite a bit of downstream work (updating all Redux libs, such as thunk, epics, futures, dev tools and more). Therefore, we've held off on making that change for now, in case we see more breaking changes that we want to make to the library and we can bundle them all together.

@hramnathnayak
Copy link

hramnathnayak commented Dec 11, 2018

In action add a completer and in constructor set it to future.

class MyAction {
Completer completer;
MyAction(this.completer) {
completer.future;
}
}

// in current actions middleware when done set future to complete
if (action is MyAction) {

 // do MyAction

  action.completer.complete()

}

in middleware do this
MyAction.completer.future.whenComplete(() async {
//do something else
}

}

jimsimon added a commit to jimsimon/redux_thunk that referenced this issue Jan 21, 2019
This resolves issue brianegan#12 and provides a built-in workaround
for brianegan/flutter_redux#65
jimsimon added a commit to jimsimon/redux_thunk that referenced this issue Jan 22, 2019
This resolves issue brianegan#12 and provides a built-in workaround
for brianegan/flutter_redux#65
jimsimon added a commit to jimsimon/redux_thunk that referenced this issue Jan 22, 2019
This resolves issue brianegan#12 and provides a built-in workaround
for brianegan/flutter_redux#65
@vijaykanta
Copy link

Hey there -- Yah, we need to fix dispatch so it returns the action from the dispatch call. Please see johnpryan/redux.dart#26.

In the meantime, you can do something like this:

final resultA = doSomething();
final resultB = doSomethingElse();

store.dispatch(resultA);
store.dispatch(resultB);

Future.wait([
  resultA,
  resultB,
]).then(() => {
  console.log('I did everything!');
});

I still don't understand and cannot make this work in my own code.
First I wrote a thunk function that does some async processing and when it ends, calls another store.dispatch within to update a message store variable.

How can I wait for the thunk to complete and read the updated message? I was finding answer in this thread, but to no avail. The function returns a thunk action which does some async process within and meanwhile the code that called is finished and I cannot know if the message variable is changed because it doesn't know when it updates.

The code
store.dispatch(thunkAction)
doesn't really wait as the next line of code that checks for message doesn't change at all as they are synchronous. Hope I made sense.

@stevenspiel
Copy link

@vijaykanta I've had success with assigning a Completer in the action's constructor.

class DoSomethingAction {
  final Completer completer;

  DoSomethingAction({
    dynamic someArg,
    Completer completer,
  }) : this.completer = completer ?? Completer();
}

Then, in you're Future.wait list, you can use the completer's future:

final resultA = DoSomethingAction(someArg: 1);
final resultB = DoSomethingAction(someArg: 2);

store.dispatch(resultA);
store.dispatch(resultB);

Future.wait([
  resultA.completer.future,
  resultB.completer.future,
]).then(() => {
  console.log('I did everything!');
});

Of course, you'll need to complete the action somewhere, which I do in my middleware:

...
  return (store, action, next) {
    next(action);

    doSomething().then((_) => action.completer.complete())
  };
...

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

No branches or pull requests

5 participants