riverpod FutureProvider will keep firing after adding .family modifier


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

  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



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});

  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.

Answered By – KeroJohn97

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.