riverpod
riverpod copied to clipboard
whenData() should preserve the value of AsyncLoading()
Is your feature request related to a problem? Please describe.
Consider this gist: https://dartpad.dev/?id=ba69a9c1066bed38ea72ec8dd185f44d
This example consists of:
- a FutureProvider
userProvider
that loads user data - an intermediary provider
firstNameProvider
that uses .selectAsync to extract the first name - a final provider
greetingProvider
that watches the intermediary provider and returns a greeting for the user
When the userProvider
is invalidated, the UserProvider becomes an AsyncData(<old value>, isLoading:true)
and finally switches to AsyncData(<new value>)
.
The firstNameProvider
however becomes a AsyncLoading<String>(value: userProvider
updates, since .selectAsync
returns a future which is only resolved on the next tick of the event loop.
And the greeting provider, which uses .whenData() on firstNameProvider
, will be AsyncLoading()
without any value.
See this print of the values of these providers in the given sample:
AsyncData<({String firstName, String id, String lastName})>(value: (firstName: Abigail 902, id: 902, lastName: Miller))
AsyncLoading<String>(value: Abigail 538)
AsyncLoading<String>()
The first line is the userProvider
with the new, updated value.
The second line is the firstnameProvider
which still has the old name as value, because the future returned by .selectAsync still has to resolve, indicated by the AsyncLoading
type.
The third line however does not have any value at all and is just an AsyncLoadin(), because it calls .whenData
on an AsyncLoading()
which does not preserve the value.
This causes a one-frame loading state on the widget that reads the greeting provider.
Describe the solution you'd like
I would propose a change to .whenData((data) => mapper(data))
to transform an AsyncLoading(value)
to an AsyncLoading(mapper(value))
instead of an AsyncLoading()
without value.