so I have future provider like this
final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, List<String>>((ref, cartCodes) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: cartCodes);
});
as you can see, I pass cart codes ( List<String>
) as a parameter for my FutureProvider
and then I use it like this
@override
Widget build(context, ref) {
final List<String> cartCodes = carts.map((cart) => cart.code).toList();
final additionalCostsProviderAsynValue = ref.watch(additionalCostsProvider(cartCodes));
return Scaffold(
body: additionalCostsProviderAsynValue.when(
loading: () => CircularProgressIndicator(),
error: (error, stackTrace) {
return ErrorDisplay(
onButtonClicked: () => ref.refresh(additionalCostsProvider(cartCodes)),
);
},
data: (results) {
return Container();
},
),
);
}
and then it will make my app request to the server over and over again.
I believe the problem is on the .family
modifier. because if change the FutureProvider
without using .family
like the code below, the problem will not occurred.
final additionalCostsProvider = FutureProvider.autoDispose<List<ExtraCost>>((ref) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: ["BA3131"]); // <--- if I hardcode it in here, the problem will not occurred
});
CodePudding user response:
https://riverpod.dev/docs/concepts/modifiers/family/#parameter-restrictions
This is the official documents for the Riverpod modifier .family.
For families to work correctly, it is critical for the parameter passed to a
provider to have a consistent hashCode and ==.
Since it is constant, you have to declare a class for it, you can create a class like below, using package Equatable.
class ExtraCostParameter extends Equatable {
final List<String> cartCodesList;
const ExtraCostParameter({required this.cartCodesList});
@override
List<Object?> get props => [cartCodesList];
}
And your new future provider will look like this.
final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, ExtraCostParameter>((ref, param) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: param.cartCodesList);
});
On the other hand, if your List<String>
is not constant, you may want to use .autoDispose.
Hopefully it works.