I am new to flutter and dart so the answer to this may be simple, or I may be going about this COMPLETELY the wrong way.
I basically want to use Provider for state management, and Shared Preferences for local storage.
I have a class called 'ResolutionsProvider' which contains a list of custom 'Resolution' objects which are used throughout my app. It contains methods for adding and removing Resolutions and it all works fine.
The problem is that I want the data to be persistent if the user restarts the app...
I'm trying to use SharedPreferences for this so I have methods within 'ResolutionsProvider' to save data to, and load data from Shared Preferences...
I know through print calls that the data is saving to shared preferences correctly...
My (potentially wrong) thinking is that I need to achieve the following...
- App is run
- ResolutionsProvider is instantiated as a ChangeNotifierProvider
- ResolutionsProvider.loadData() is run to populate List from SharedPreferences...
I've tried to call ResolutionsProvider.loadData() from within an initState but I get the following error...
E/flutter (30660): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: dependOnInheritedWidgetOfExactType<_InheritedProviderScope<ResolutionsProvider?>>() or dependOnInheritedElement() was called before _AppState.initState() completed.
E/flutter (30660): When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.
E/flutter (30660): Typically references to inherited widgets should occur in widget build() methods. Alternatively, initialization based on inherited widgets can be placed in the didChangeDependencies method, which is called after initState and whenever the dependencies change thereafter.
So i guess the question is two fold...
If my approach is correct, how do I call the 'loadData' method to populate my provider on booting the app if I can't do so within initState
If my approach is incorrect, what's the right approach to achieve my basic objective?
Here's my main.dart code
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await LocalStorage.init();
runApp(
ChangeNotifierProvider(
create: (context) => ResolutionsProvider(),
child: const App(),
),
);
}
Here's the relevant code from my App.dart
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
@override
void initState() {
loadData();
print("app initialised");
super.initState();
}
void loadData() async {
await Provider.of<ResolutionsProvider>(context).loadResolutions();
}
@override
Widget build(BuildContext context) {
return MaterialApp(blah blah blah);
Here's the relevant parts of my ResolutionProvider.dart
class ResolutionsProvider extends ChangeNotifier {
List<Resolution> resolutions = [];
// Interfacing with Shared Preferences
loadResolutions() async {
resolutions = await LocalStorage.getResolutions();
print('${resolutions.length} resolutions loaded');
// notifyListeners();
}
saveResolutions() async {
LocalStorage.saveResolutions(resolutions);
}