flutterriverpodflutter-isar

Stop rebuilding when using FutureProviderFamily


I have a Flutter app which uses FutureProviderFamily to fetch List of items from an Isar database.

final FutureProviderFamily<List<Card>, Card> searchCardProvider =
    FutureProvider.family(
  (FutureProviderRef<List<Card>> ref, Card card) async {
    final CardUtil cardUtil = await ref.watch(cardUtilProvider.future);
    return cardUtil.search(card);
  },
);

The usage is as follows in the page:

@override
  Widget build(BuildContext context) => ref
      .watch(
        searchCardProvider(
          card.Card()
            ..name = _searchText
            ..cardType = _cardType,
        ),
      )
      .when(...);

The page itself has a SegmentedButton which holds card types and a TextFormField which acts as a search. The values of these items are passed to the provider.

My problem here is the build method re-runs over and over again. I have tried to use the select function but couldn't figure out how to use it for a List. Maybe there is a better way to handle this. Any suggestions?

P.S: Another FutureProvider that lists out all the data works perfectly, but unable to filter the data depending on the parameters.

final FutureProvider<List<Card>> readAllCardProvider =
    FutureProvider<List<Card>>(
  (FutureProviderRef<List<Card>> ref) async {
    final CardUtil cardUtil = await ref.watch(cardUtilProvider.future);
    return cardUtil.readAll();
  },
);

I have also tried out sending a Map instead of the Card type as the parameter to the Family but didn't work.

Thanks!


Solution

  • List<Card> is not a suitable type for a family identifier for RiverPod. As the docs say in https://riverpod.dev/docs/concepts/modifiers/family#passing-multiple-parameters-to-a-family

    Families have no built-in support for passing multiple values to a provider.

    On the other hand, that value could be anything (as long as it matches with the restrictions mentioned previously).

    This includes:

    • A tuple from tuple
    • Objects generated with Freezed or built_value
    • Objects using equatable

    A List<Card> does not have a deep equality for ==, and therefore no two evaluations will show the same family provider.

    Or, you can use a generated provider with a more robust family identifier strategy.