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;
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 Provider
s 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);