-
-
Notifications
You must be signed in to change notification settings - Fork 956
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
FutureProvider disposed and re run first time #559
Comments
gameProvider gets disposed when _characterProvider changes, in order to recreate itself based off of the new state of _characterProvider, but because you have maintainState set to true, it doesn't actually ever fully dispose, so _characterProvider has to stay alive because it is depending on it, as well as _profileProvider since _characterProvider depends on that. final gameProvider =
FutureProvider.autoDispose.family<List<String>, int>((ref, key) async {
final characterAsync = ref.watch(_characterProvider(key).last);
final character = await characterAsync;
if (character == null) return const [];
ref.onDispose(() {
print('disposed');
});
late final List<String> result;
await Future.delayed(const Duration(seconds: 2), () {
result = List.filled(10, character);
});
/// Add this print statement
print('New game provider built');
ref.maintainState = true;
return result;
}, name: 'Games Provider'); By adding the print statement you will see the problem. |
I understand a new game provider is built and that's why it gets disposed in the first place, but why should it build a new provider though? In this example I'm not reading
And there is only one value in Also to add a bit of context of what I'm trying to accomplish (which works, just this weird bug once) is that the user tap a widget an opens a new route with that key (the name of the character) and then _character and _gameProvider starts and fetch the list of games, if loads successfully then maintain it as cache so the next time the user taps the same character is already loaded (almost like the Marvel app example). It works but fires twices disposing the first time because of this behavior. |
Thanks for the clarification, yes this is different. It is more similar to #495. It seems like you are trying to keep the state of the previous result while emitting a new result anytime _characterProvider changes. Essentially you want a Stream not a Future: /// simulating an http call
final gameProvider =
StreamProvider.autoDispose.family<List<String>, int>((ref, key) async* {
await for (final character in ref.watch(_characterProvider(key).stream)) {
if (character == null) {
yield const [];
} else {
ref.onDispose(() {
print('disposed');
});
late final List<String> result;
await Future.delayed(const Duration(seconds: 2), () {
result = List.filled(10, character);
});
yield result;
}
}
}, name: 'Games Provider'); |
Thank you for your time, your example is really nice and I will use it for some other things (:wink:) but in this particular example I don't mind the previous state (diffrence with #495 is I'm filtering the profile within the streamProvider distinct method), if the Right now |
Ahh, sorry for talking about something else again. However, I believe this issue was fixed in the 1.0.0-dev.0 version of riverpod. At least I'm no longer seeing the 2nd rebuild after migrating this code. Specifically in the CHANGELOG I see this: StreamProvider.last, StreamProvider.stream and FutureProvider.future now expose a future/stream that is independent from how many times the associated provider "rebuilt":
|
I haven't tested it using the last dev 1.0.0 but the CHANGELOg you mention and saying that the 2nd rebuild doesn't appear after migration means that problem was fixed and it was some minor bug so if there is nothing else I will close this issue |
Following the case of #243 I am experiencing a similar issue but I'm not sure is the same edge case. I have 3 providers
To avoid unnecessary boilerplate this is a minimal reproducible example without a local or web repositories
From this project
gameProvider
is disposed and fired again, (I/flutter ( 4643): disposed
),_profileProvider
and_characterProvider
don't get disposedThe text was updated successfully, but these errors were encountered: