marcglasberg / async_redux

Flutter Package: A Redux version tailored for Flutter, which is easy to learn, to use, to test, and has no boilerplate. Allows for both sync and async reducers.
Other
234 stars 40 forks source link

How to return something when an Action is done? #13

Closed ghost closed 5 years ago

ghost commented 5 years ago

The RefreshIndicator's onRefresh wants a Future Function(), that returned Future must complete when the refresh operation is finished.

Before I would make the call to the API first and then when the response returns I would dispatch an (synchronous) Action and return null.

Now with ReduxAction that can reduce async, I move the API call inside the Action, but what would be the proper way to return something as soon as the Action is finished ?

StoreConnector<AppState, Overview>(
  converter: (store) => store.state.overview,
  builder: (context, overview) {
    return overview == null
      ? Center(child: CircularProgressIndicator())
      : RefreshIndicator(
        onRefresh: () {
          StoreProvider.of<AppState>(context, 'refresh').dispatch(GetOverview());
          return Future.delayed(Duration(seconds: 1));
          /// Before I did this:
          //return ApiService().getOverview().then((Overview ov) {
          //  StoreProvider.of<AppState>(context, 'refresh').dispatch(SetOverview(ov));
          //  return null;
          //}
        },
        child: ListView(...),
marcglasberg commented 5 years ago

I'm not sure I understand your question. But if you want an action to notify when it finished doing some stuff, you could create a Future and pass its completer to the action, as a parameter to its constructor. Then you return that Future. The action would complete the future as soon as it has finished doing its thing. Does that make sense?

ghost commented 5 years ago

Thank you for the help (I first tried to solve this with Events).

On another note, I'm not quite sure if this not something I should do or not. Is it discouraged to dispatch Actions without putting them as Callbacks in a ViewModel?

If not, then a Function something like this in the StoreProvider would be great, to easily dispatch Actions:

static void dispatch<St>(BuildContext context, ReduxAction action, Object debug) {
  StoreProvider.of<St>(context, debug).dispatch(action);
}
marcglasberg commented 5 years ago

1) Maybe a good idea is for me to create a dispatchGetFuture that already returns you a Future as soon as the action completes. You would use it for things like the RefreshIndicator that need a Future that tells you when the action completes.

2) I don't think there is anything inherently wrong with getting the store and doing direct dispatches without the ViewModel or even without the StoreConnector, directly inside of the widget. However: • If you have the StoreConnector without the ViewModel it will rebuild everytime. The new ViewModel being equal to the previous one is what prevents the widget from rebuilding. So if you need the ViewModel anyway, do you actually gain anything by not creating the callbacks? • I think that would make more sense if you want to dispense with the StoreConnector altogether, and dispatch actions directly from the final widget . But when you do it with the StoreConnector you force yourself to cleanly separate the widget from the way it gets its data. So, it's better for clean code, and helps a lot with tests later. How would you test the RefreshIndicator if you don't have the Connector? You would have to create the store, and dispatch an action. And maybe you would have to use the StoreTester, and mock the action. However, if you use the Connector/Dumb-Widget architecture you just need to use a callback in your tests, which is much easier to setup.

In any case I don't claim to be an authority in all kinds of possible architecture designs with Redux or even with AsyncRedux. So, I may be wrong.

marcglasberg commented 5 years ago

https://github.com/marcglasberg/async_redux/issues/14

marcglasberg commented 5 years ago

https://github.com/marcglasberg/async_redux/pull/16

marcglasberg commented 5 years ago

This is now live: version: 1.3.8.

marcglasberg commented 5 years ago

Are @SunlightBro and @SunlightDave the same person? I did some changes in main_dispatch_future.dart, (including changing the file name), but you are the author. If you want you can list yourself as the author in the top file comment.

SunlightBro commented 5 years ago

Yes same person, just keep it the way its is.