i'm new to use Provider integrate with go_router in Flutter follow by MVVM pattern. Problem happen when my Provider class needs initial value in constructor.
Let's say we have 2 screens with its view models: Screen1
with ViewModel1
and Screen2
with ViewModel2
. The approach we normally see is that:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => ViewModel1()),
ChangeNotifierProvider(create: (context) => ViewModel2()),
],
child: const MyApp(),
),
);
But in my case, ViewModel2
is a PDP screen and it needs an ID parameter (to call api get detail) which passed from Screen1
, because of that, we can not init 2 Providers at the root of the app like above.
I've tried to refactor the structure a bit, instead of create Providers at the root of app, i create Provider (view model) when screen is open by creating a base class, like this:
abstract class BaseScreen<Vm extends BaseViewModel> extends StatelessWidget {
Vm createViewModel();
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: ChangeNotifierProvider(
create: (_) => createViewModel(),
child: ...
),
);
}
}
And 2 screens will extend this BaseScreen
and 2 view models will extend BaseViewModel
, like this:
class Screen2 extends BaseView<ViewModel2> {
final int id;
@override
Screen2 createViewModel() => ViewModel2(id);
...
It's works fine at the beginning. But the issue happen, i cannot access the previos Provider in ViewModel2
by using context.read<ViewModel1>()
, it throw error cannot find Provider in widget tree.
So i've checked the widget tree, (which using go_router for navigation), and it's look similar to this:
Widget Tree Image
The outer screen is not wrap it's sub routes, all the screen is the same level, children of root, so that context.read<ViewModel1>()
cannot find the previous Provider.
You guys have any solutions for this problem? Thank you in advanced.