Reputation: 1332
I have a Flutter Notifier MyClassProvider
whose value is an instance of a class, e.g.:
class MyClass {
String propertyA;
String propertyB;
String propertyC;
}
The Notifier's instance propertyA
value is dependent on a different provider otherProvider
, while the other properties propertyB
and propertyC
are both independent from it.
So first, I tended to:
A) Use the previous state
of the notifier in its build()
method to only ever adapt the value of propertyA
within its build()
method, and take up the previous property values for propertyB
and propertyC
from that state
, e.g. like:
--------------
Notifier file ('MyClassProvider'):
--------------
.
.
.
/// 'async' because the build() method of the 'otherProvider' is async
Future<MyClass> build() async {
final otherProvidersValue = await ref.watch(otherProvider.future);
final newAValue = await computeNewAValueFromOtherProviderValue(otherProvidersValue);
/// Calculate value of `propertyA` based on value of 'otherProvider' & leave
/// rest untouched
return MyClass(
propertyA: newAValue,
propertyB: state.value != null ? state.value!.propertyB : 'defaultB',
propertyC: state.value != null ? state.value!.propertyC : 'defaultC',
);
}
.
.
.
But then I came across the section of the riverpod docs saying:
DON'T perform side effects during the initialization of a provider
Although I don't consider the build()
method of otherProvider
to be a side-effect (it simply corresponds to an asynchronous data fetch, which can in turn however be triggered by other operations in the application), I looked for the following workaround, also because the fact that the providers' build()
method is asynchronous due to its direct dependency from otherProvider
is somewhat of a pain:
B) Leave the notifiers' build()
method to be synchronous and code its dependency using ref.listen(otherProvider)
and a callback executing the desired operation at the app root level, e.g.:
--------------
Notifier file ('MyClassProvider'):
--------------
.
.
.
/// no longer 'async' because dependency of the 'otherProvider' is managed outside notifer
MyClass build() {
return MyClass(
propertyA: 'defaultA',
propertyB: 'defaultB',
propertyC: 'defaultC',
);
}
.
.
.
--------------
Apps Root Widget file:
--------------
.
.
.
build() {
ref.listen(otherProvider, (_, newValue) {
newValue.when(
data: (newlyProvidedValue) async {
final newValueA = await computeNewAValueFromOtherProviderValue(newlyProvidedValue);
/// Update Notifiers' State according to the new value of 'otherProvider'
ref
.read(MyClassProvider().notifier)
.updatePropertyA(
updatedValue: newValueA,
);
}
},
error: (error, traceStack) {
/// Handle Error
},
loading: () {
/// Handle Loading Animation
},
);
});
.
.
}
.
.
.
.
I now wonder if there's any technical problem with the approach I use in B), and if so, if it is even "permitted" to use the state
in the build()
method of a provider as I do in A) ?
My application never crashed for either, but my experience with Flutter + State Management with Riverpod is limited, so I wanted to double-check.
Upvotes: 0
Views: 261