Home > database >  LateInitializationError: Local 'prefs' has not been initialized
LateInitializationError: Local 'prefs' has not been initialized

Time:09-30

I am working with riverpod and flutter_hooks

I am trying to get implement shared_prefrences using this 2 approaches and this is what I get to so far :

pref_changenotifier.dart

import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';

const _isloggedkey = 'logged';
const _boardingkey = "boarding";
const _apiTokenkey = 'apitoken';
const _rolekey = 'role';

class PrefChangeNotifier with ChangeNotifier {
  late final SharedPreferences _sharedPreferences;

  PrefChangeNotifier(this._sharedPreferences) {
    getPref();
    notifyListeners();
  }

  bool? _islogged;
  bool? _boarding;
  String? _apitoken;
  String? _role;

  String get apitoken => _apitoken!;
  String get role => _role!;
  bool get islogged => _islogged!;
  bool get boarding => _boarding!;

  void getPref() async {
    _islogged = _sharedPreferences.getBool(_isloggedkey);
    _apitoken = _sharedPreferences.getString(_apiTokenkey);
    _boarding = _sharedPreferences.getBool(_boardingkey);
    notifyListeners();
  }

  void setLoggedValue(bool logged) async {
    await _sharedPreferences.setBool(_isloggedkey, logged);
    _islogged = logged;
    notifyListeners();
  }

  void setTokenValue(String apitoken) async {
    await _sharedPreferences.setString(_apiTokenkey, apitoken);
    _apitoken = apitoken;
    notifyListeners();
  }

  void setBoardingValue(bool boarding) async {
    await _sharedPreferences.setBool(_boardingkey, boarding);
    _boarding = boarding;
    notifyListeners();
  }

  void setRoleValue(String role) async {
    await _sharedPreferences.setString(_rolekey, role);
    _role = role;
    notifyListeners();
  }

  void clearAllValues() async {
    await _sharedPreferences.clear();
    notifyListeners();
  }
}

pref_provider.dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'pref_changenotifier.dart';

import 'package:shared_preferences/shared_preferences.dart';

final sharedPreferences = FutureProvider<SharedPreferences>(
    (ref) async => await SharedPreferences.getInstance());

final prefChangeNotifierProvider =
    ChangeNotifierProvider<PrefChangeNotifier>((ref) {
  final sharePreferencesData = ref.watch(sharedPreferences).asData;
  late final SharedPreferences prefs;

  if (sharePreferencesData != null) {
    prefs = sharePreferencesData.value;
  }

  return PrefChangeNotifier(prefs);
});

But whenever I call it using : ref.read(prefChangeNotifierProvider).setBoardingValue(true); , it throws this error

E/flutter (22947): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: An exception was thrown while building ChangeNotifierProvider<PrefChangeNotifier>#05878.
E/flutter (22947):
E/flutter (22947): Thrown exception:
E/flutter (22947): An exception was thrown while building _NotifierProvider<PrefChangeNotifier>#3bb8a.
E/flutter (22947):
E/flutter (22947): Thrown exception:
E/flutter (22947): LateInitializationError: Local 'prefs' has not been initialized.
E/flutter (22947):
E/flutter (22947): Stack trace:

i know that the problem is with my late initialization but what should i do ?

CodePudding user response:

Yes isn't that's obvious? You're using late final SharedPreferences prefs, then you use prefs = sharePreferencesData.value. You haven't initiated that variable, so you cannot do anything on it. You could change it to: final SharedPreferences prefs = await SharedPreferences.getInstance() in async function.

One more problem about your code, when you call getBool(), getString()..., it could be null (if you haven't saved anything on your shared preference). You could use something like this:

isLogin = prefs.getBool(SHARED_PREFS_KEY_LOGIN) ?? false;

CodePudding user response:

put this method in PrefChangeNotifier class

static Future initMySharedPreferences() async {
   _sharedPreferences = await SharedPreferences.getInstance();
}

and initialize in main.dart

void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   await PrefChangeNotifier.initMySharedPreferences();
   runApp(MyApp());
 }
  • Related