I am unable to access the Provider in a Widget that I pushed onto the current Navigator:
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyModel with ChangeNotifier {
String a = 'Test1';
String b = 'Test2';
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: ChangeNotifierProvider(
create: (context) => MyModel(),
child: MyHomePage()
)
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Consumer<MyModel>(
builder: (context, myModel, child) =>
Scaffold(
appBar: AppBar(
title: Text(myModel.a),
),
floatingActionButton: FloatingActionButton(
onPressed: () =>
Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => Page2(),
),
),
tooltip: 'Press',
child: Icon(Icons.add),
),
)
);
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
var myModel = Provider.of<MyModel>(context); // A
return Scaffold(
appBar: AppBar(
title: Text(myModel.b),
),
);
}
}
I get this error:
The following ProviderNotFoundException was thrown building Page2(dirty):
Error: Could not find the correct Provider<MyModel> above this Navigator Widget
The issue seems to be that the BuildContext object in the Page2 widget is not the same BuildContext that's associated with the Provider. If I pass a reference of original context to Page2 and use that at point (A), everything works, but this doesn't seem to be a good way of solving this problem.
I tried the solution here, by using Navigator.of(context, rootNavigator: true).context
as the context inside the build
method of Page2, but I still get the same exception.
Yo must pass provider in root widget such that you can access from any where when you navigate to another page the model is not available so you must pass the provider to the parent of MaterialApp as
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyModel with ChangeNotifier {
String a = 'Test1';
String b = 'Test2';
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => MyModel(),
child: MaterialApp(title: 'Flutter Demo', home: MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Consumer<MyModel>(
builder: (context2, myModel, child) => Scaffold(
appBar: AppBar(
title: Text(myModel.a),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
Page2(),
),
),
tooltip: 'Press',
child: Icon(Icons.add),
),
));
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
var myModel = Provider.of<MyModel>(context); // A
return Scaffold(
appBar: AppBar(
title: Text(myModel.b),
),
);
}
}