I have a parent ChangeNotifier ParentProvider
, and 2 other providers extend the ParentProvider
;
ChildProviderA
, ChildProviderB
.
I have a route which is called MyScreen
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
if(ModalRoute.of(context).settings.arguments != null){
return ChangeNotifierProvider(
create: (context) => ChildProviderA(),
child: _Screen()
);
}
return ChangeNotifierProvider(
create: (context) => ChildProviderB(),
child: _Screen()
);
}
}
depending on the arguments I want to use a provider, and in either case, I want to call a function called initData()
in the ParentProvider
from the _Screen
widget.
@override
Widget build(BuildContext context) {
...
Provider.of<ParentProvider>(context, listen: false).initData();
...
}
This gives me an error
Error: Could not find the correct Provider<ParentProvider> above this _Screen Widget
If I used Provider.of<ChildProviderA>(context, listen: false).initData();
or Provider.of<ChildProviderB>(context, listen: false).initData();
It works, but I want in either child Provider used, to be able to call initData.
How can this be done ?
Provider.of
looks for provider with exactly given type. It doesn't include child types.
If the child screen needs to access some different data having same format, you can use the same provider in both cases passing it different data through constructor:
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (condition) {
return ChangeNotifierProvider(
create: (context) => ParentProvider(data1),
child: _Screen(),
);
}
return ChangeNotifierProvider(
create: (context) => ParentProvider(data2),
child: _Screen(),
);
}
}
If you really have two different ChangeNotifier implementations sharing same interface, you can provide and access them using parent type:
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (condition) {
return ChangeNotifierProvider<ParentProvider>(
create: (context) => ChildProviderA(),
child: _Screen(),
);
}
return ChangeNotifierProvider<ParentProvider>(
create: (context) => ChildProviderB(),
child: _Screen(),
);
}
}