Open saibotma opened 3 months ago
After thinking about the issue, I now understand the reason behind the error messages.
However, what I still don't understand is what the recommended way to call the notifier is in this case?
I did not expect that I may not use the notifier variable from build
inside the onChanged
callback. I mean it makes sense after thinking about it, but it is not apparent for a beginner, and also not very intuitive. I am happy to enhance the documentation on this topic, after I got confirmation, that my reasoning is correct.
You're correct, this is indeed quite unintuitive. I need to think about the desirable behaviour here.
A simpler reproduction is:
@riverpod
class MyViewModel extends _$MyViewModel {
@override
String build() => ref.watch(myStateProvider);
void crash() {
ref.read(myStateProvider.notifier).state = 'Foo';
ref.read(myStateProvider);
}
}
Although this is consistent with how the assert behaves, that's wayy too inconvenient. I'll change this.
This is probably going to stay like this for some time. I can't immediately think of a good alternative that's not just "disable the assert".
For now, it seems to be a bit niche. If this gets a bunch of 👍 I'll consider it more.
You're correct, this is indeed quite unintuitive. I need to think about the desirable behaviour here.
A simpler reproduction is:
@riverpod class MyViewModel extends _$MyViewModel { @override String build() => ref.watch(myStateProvider); void crash() { ref.read(myStateProvider.notifier).state = 'Foo'; ref.read(myStateProvider); } }
Although this is consistent with how the assert behaves, that's wayy too inconvenient. I'll change this.
So we can not read state immediately after change the state. Sometimes I got this exception but didn't know what happened. I thought it should be safe because riverpod was in the same isolate.
Indeed. As I said I'll likely change this, but at the moment I need to think about how. And it doesn't seem like a very active issue, so we'll see
Here as well, hopefully it can be resolved
@dumikaiya Please thumb up the issue when you support it!
please thumbs up this issue guys
Also does anyone know a workaround this? Currently I just wrap the ref.read(provider.notifier).state = value
in a Future. I think it rebuilds the widget later with the newly added or changed value
I currently use something like this, is it okay? or can it cause unexpected errors?
Thanks
@riverpod
class MyViewModel extends _$MyViewModel {
@override
String build() => ref.watch(myStateProvider);
void crash() {
try{
ref.read(myStateProvider.notifier).state = 'Foo';
ref.read(myStateProvider); // usually ref.read(otherNotifier).someMethod();
} catch (e) {
if (e is AssertionError) {
if (e.toString().contains(
'Cannot use ref functions after the dependency of a provider changed but before the provider rebuilt')) {
} else {
rethrow;
}
} else {
rethrow;
}
}
}
}
I'll tackle this in a few weeks. I do plan in fixing this before the official 3.0 release.
Describe the bug This example has got two providers, one state provider, which persists the entered text, and a view model provider, which forwards the entered text from the state provider & also forwards the input event to the state provider. The example is very stripped down, and obviously you could do the same thing with only one provider, without any issue, however the issue appeared in a more complex real world situation where two providers were necessary.
To Reproduce
The exception disappears when you move the read the notifier inside the
onChanged
callback or stop watching the view model provider, as indicated in the comments.Expected behavior No exception should be thrown.