flutterdartflutter-change-notifier

Cannot pass function as argument to constructor of class extended ChangeNotifier


I'm trying to write a provider class with ChangeNotifier. Because the class is designed to be generic so the data inside is generic, so I thought of passing detail extraction function to this provider class.

Here is what I have written so far.

class MapProvider<T> with ChangeNotifier {
  String Function(T) idExtract;

  List<T> _locationList = [];
  T? _selectedLocation;

  MapProvider(this.idExtract);
...

And use it like this.

return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => MapProvider(
            (pin) => (pin as ILocationPin).id,
          ),
        ),
      ],
      child: MapConsumerWidget()
    )

However, an error was thrown with red screen: Error: Could not find the correct Provider<MapProvider<dynamic>> above this MapConsumerWrapper widget. I tried changing the type of idExtract to primitive type like int and the code works. Why is that, and how to fix it if possible?

Edit: Added the code utilizing the notifier with Provider.of(context).

MapConsumerWrapper()

    final mapProvider = Provider.of<MapProvider>(context, listen: false);
    final providerState = Provider.of<MapProvider>(context);
    final selectedPin = providerState.selectedLocation;
    final locationList = providerState.locationList;

Solution

  • The problem is indeed the type parameter for the MapProvider. By default a dynamic is used, so Provider.of<MapProvider>(context) is actually a Provider.of<MapProvider<dynamic>>(context).

    It is good to always set the type parameter in Providers and similar (like ChangeNotifierProvider, so that it's always clear what type you are actually providing down the tree (so that it can be fetched with Provider.of:

    ChangeNotifierProvider<MapProvider<String>>(
      create: (_) => MapProvider(
        (pin) => (pin as ILocationPin).id,
      ),
    ),
    

    and then

    final providerState = Provider.of<MapProvider<String>>(context);