I'm trying to build a Notes app with backup and restore functionality. I have a home page that shows up when the app is opened. This page has a Scaffold as it's body, which in turn has a drawer that has ListTiles for backup and restore. I use a HomeBloc object to interact with the database where I save the notes, hence I used Provider to get access to it everywhere.
The ListTiles open a MaterialPageRoute to new screens where the user is prompted to choose the file, enter passwords etc.
When I tap on the Restore ListTile in the drawer, I get this error:
The following ProviderNotFoundException was thrown building RestoreLocalBackupPage(dirty, state: _RestoreLocalBackupPageState#4f937):
Error: Could not find the correct Provider<HomeBloc> above this RestoreLocalBackupPage Widget
This likely happens because you used a `BuildContext` that does not include the provider
of your choice.
This is my main.dart, where I wrap the Home page in a Provider:
void main() {
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Notes',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Provider(
create: (_) => HomeBloc(),
child: HomePage(),
)
);
}
}
This is the build method of my HomePage:
Widget build(BuildContext context) {
homeBloc = Provider.of<HomeBloc>(context);
return Scaffold(
backgroundColor: Color.fromRGBO(219, 243, 250, 1),
appBar: AppBar(...),
body: StreamBuilder<List<Note>>(...),
floatingActionButton: FloatingActionButton(...),
drawer: HomeDrawer(),
);
}
The HomeDrawer's build method returns a Drawer, which has a ListView as it's child. Here's the code for the ListTile that launches the Restore Backup page:
ListTile(
title: Text('Local Backup',
style: GoogleFonts.sourceSansPro(
textStyle: TextStyle(fontWeight: FontWeight.w500),
fontSize: 16)),
onTap: () async {
// Update the state of the app
// ...
// Then close the drawer
bool permissionGranted = await _getPermissions(context);
if (permissionGranted) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => CreateLocalBackupPage(
currentBackupDirectory: currentBackupDirectory
),
)
);
}
},
)
This is the error that I get when I tap on the above ListTile:
The following ProviderNotFoundException was thrown building RestoreLocalBackupPage(dirty, state: _RestoreLocalBackupPageState#4f937):
Error: Could not find the correct Provider<HomeBloc> above this RestoreLocalBackupPage Widget
This likely happens because you used a `BuildContext` that does not include the provider
of your choice.
HomeDrawer()'s BuildContext does have access to the HomeBloc object I need. Hence, wrapping the RestoreLocalBackupPage widget inside another Provider works:
HomeBloc homebloc = Provider.of<HomeBloc>(context);
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Provider(
create: (_) => homebloc,
child: RestoreLocalBackupPage(currentBackupDirectory: currentBackupDirectory),
)
)
);
I wanted to know if there's a simpler, more elegant way of getting access to HomeBloc inside RestoreLocalBackupPage using Provider. Dependency Injection via the constructor works but that sort of defeats the purpose of using Provider in the first place, right?