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

Using flutter redux and Refresh Indicator #6

Closed
oli107 opened this issue Jan 29, 2018 · 12 comments
Closed

Using flutter redux and Refresh Indicator #6

oli107 opened this issue Jan 29, 2018 · 12 comments

Comments

@oli107
Copy link

oli107 commented Jan 29, 2018

Hi,

Great library, I've really enjoyed implementing it but I've had a bit of a mammoth session and can't seem to wrap my head around this one. I am pretty new to Flutter and Dart so apologies if this is a simple question.

I want to use a pull to refresh which sends an action and retrieves a new set of items from the web via the middleware. Doing this without the refresh indicator works well, but the indicator needs a Future passed to it that resolves when the action has finished. Is there any way that I can use the existing stock widget to start and stop based on actions?

Thanks

@brianegan
Copy link
Owner

Ah, that's an interesting one. Thanks for writing in i'm on vacation for a few days, but I'll take a look at this and bit more carefully when I'm back in action early next week to see if I can make something easy to use :)

@oli107
Copy link
Author

oli107 commented Jan 30, 2018

That's great, thanks @brianegan . Enjoy your vacation!

@brianegan
Copy link
Owner

brianegan commented Feb 14, 2018

Hey hey, sorry about the delay! Came back to quite a bit of work :)

Here's the best solution I could think of:

  1. Create an Action that contains a Completer
  2. Return the action.completer.future to the onRefresh function of the RefreshIndicator
  3. Write a Middleware that listens for this action. It handles:
    * Making an async call to a database or web api
    * After the async call completes, does the normal thing: dispatches an action with some payload
    * Also performs action.completer.complete. This will inform the RefreshIndicator that the async work is complete, and will hide the spinner.

Example here: https://github.com/brianegan/flutter_redux/blob/refresh-indicator-example/example/lib/main.dart#L10

I'll try to think if there's a good way to make this easier in some way... Maybe a generic action or middleware.

@oli107
Copy link
Author

oli107 commented Feb 17, 2018

Brian,
This worked brilliantly and was not difficult to implement (thanks to your great example!). I'm new to dart so was not aware of completers. Thanks for your help and great library once again.

@oli107
Copy link
Author

oli107 commented May 11, 2018

Brian,

Since the move to Dart2, I don't seem to be able to use a Completer in the middleware. Is there a way around this or a better way to manager the refresh indicator now?

Thanks

@oli107 oli107 reopened this May 11, 2018
@brianegan
Copy link
Owner

Heya @oli107. Hrm, that's interesting -- I haven't run into that problem with Dart 2 + Completers. Is the Completer just not working, or are you running into type errors of some kind?

@oli107
Copy link
Author

oli107 commented May 12, 2018

I'm profusely apologetic @brianegan - I think that was a case of me working on this too late at night! Typo on my part caused a type error, but it is fixed and working. I'll re-close the issue. Next challenge - work out how to animate things whilst using redux...

@oli107 oli107 closed this as completed May 12, 2018
@brianegan
Copy link
Owner

Hah, no worries at all :) We've all been there!

@heyphat
Copy link

heyphat commented Jul 16, 2018

Hi there,
Thank for the great library. I ran into this exact problem. I am using flutter redux with dart 2. I also read the example you gave above. But I couldn't make it work.
This is the error message I got:
I/flutter ( 5098): The following assertion was thrown building StreamBuilder<_ViewModel>(dirty, state: I/flutter ( 5098): _StreamBuilderBaseState<_ViewModel, AsyncSnapshot<_ViewModel>>#cc65e): I/flutter ( 5098): type '() => Future<dynamic>' is not a subtype of type '() => Future<Null>'
The weird thing is the program still compiles and application is running, but when I swipe down to refresh. The program stop working as spinner does not disappear and that error message print in the console.

@brianegan
Copy link
Owner

Heya @tanphathuynh -- yep, that's a standard type error, which Dart 2 is now more strict about. In this case, the completer must now be a Completer<Null> rather than a plain old Completer (which is inferred as a Completer<dynamic>.

@harshvardhan
Copy link

harshvardhan commented Jun 4, 2019

Hey hey, sorry about the delay! Came back to quite a bit of work :)

Here's the best solution I could think of:

1. Create an Action that contains a `Completer`

2. Return the `action.completer.future` to the `onRefresh` function of the `RefreshIndicator`

3. Write a `Middleware` that listens for this action. It handles:
   * Making an async call to a database or web api
   * After the async call completes, does the normal thing: dispatches an action with some payload
   * Also performs `action.completer.complete`. This will inform the RefreshIndicator that the async work is complete, and will hide the spinner.

Example here: https://github.com/brianegan/flutter_redux/blob/refresh-indicator-example/example/lib/main.dart#L10

I'll try to think if there's a good way to make this easier in some way... Maybe a generic action or middleware.

Hey, thanks for the awesome work and continuous support.

For this issue, can we wrap every object in the state inside another object which contains the information about the status, the actual data (Generic) and a message. Something like this:

Resource{
dynamic data, 
String status, 
dynamic message
}

Making three plausible condition as follows:

  1. When there is an API or DB call, we can tell reducer to return this object:
    Resource(null, Status.LOADING, "Entity Loading")

  2. When there is response from API or DB
    Resource(data, Status.SUCCESS, "Entity Loaded")

  3. When there is an error in response:
    Resource(null, Status.ERROR, "Error in the Entity")

IncPlusPlus added a commit to IncPlusPlus/betterstat-mobile that referenced this issue Jun 3, 2020
…top early""

This reverts commit 3cc01f64 because apparently this is the correct way to do it, as sneaky as it seems. See brianegan/flutter_redux#6 (comment)
IncPlusPlus added a commit to IncPlusPlus/betterstat-mobile that referenced this issue Jun 3, 2020
With some effort, I have successfully managed to smuggle a new class called SpecializedCompleterTuple through some actions such that the middleware can have some influence on a UI widget which originally constructed (and is listening to the futures inside of) the SpecializedCompleterTuple. My purposes for doing this are outlined in the documentation of SpecializedCompleterTuple.

I'm justifying how jank this system is because it's not far off from what Brian Egan recommended (brianegan/flutter_redux#6 (comment)). However, I do hope I find something cleaner than this for the future. This also relates to Workiva/built_redux#103 and flutter/flutter#11675.
@hacker1024
Copy link

hacker1024 commented Apr 7, 2021

I've released a new package called declarative_refresh_indicator which takes a boolean refreshing value and is implicitly animated. This should be easier to connect to Redux state.

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

5 participants