0

enter image description here

I am using shared preferences package in flutter to store boolean values. I have stored boolean value with key name. But iam getting nosuchmenthodexception. enter image description here

Edit: Code in text

 class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      SharedPreferences pref;
    
      Future<void> addStringToSF() async {
        pref = await SharedPreferences.getInstance();
      }
    
      @override
      void initState() async {
        super.initState();
        await addStringToSF();
      }
    
      @override
      Widget build(BuildContext context) {
        bool present = pref.containsKey('name');
    
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: present == true ? Home() : Register(),
        );
      }
    }
Samuel T
  • 233
  • 2
  • 12
  • You need to wait for `prefs` to be assigned `SharedPreferences`'s instance before you can call any method on it. – Jigar Patel Apr 14 '21 at 05:33
  • I have used await on line 20 right to get the value assigned – Samuel T Apr 14 '21 at 05:38
  • Yes, but there is no `await` in line 26. – nvoigt Apr 14 '21 at 05:40
  • 1
    And please do not paste code as a picture. It's impossible to find in search engines, makes it hard for people with disabilities and screenreaders and in the end hurts yourself, because I for one could have easily copied and modified your code in my answer to show you a solution, but I will not type it all out again. I'm a programmer, not a typist. – nvoigt Apr 14 '21 at 05:42
  • @nvoigt, if i add await in line 26 then should i make my initState() an async function? – Samuel T Apr 14 '21 at 06:05

3 Answers3

3

You have not waited for your future to complete. In other words, you read from shared preferences, but basically said "I don't care if it's done yet, I'll just continue". Well, if you don't wait for it to be done, your value is not set yet.

Since it's a Stateful widget, you could assume your variable is false until your prefs variable is actually set. Once you are sure it's set, call setState, the build function will run again and will now have a valid value.

Alternatively, you could use a FutureBuilder to build your widget conditionally based on whether the future completed yet. You can find more information about that approach here: What is a Future and how do I use it?

Especially as a beginner or when coming from a different language (so basically everybody) you should install the pedantic package. It will give you a lot of warnings and hints what to do and not to do. It would have warned you of the fact that you missed to await a Future in line 26. Sure, experienced develpers see it, but it is so much easier to let a computer do it first. It's like compile errors. Sure you could find them on your own, but why would you not want your compiler to tell them which line they are on, right?

nvoigt
  • 75,013
  • 26
  • 93
  • 142
1

You need to wait for getting SharedPreference instance because this is async method,You can get like below,

Define object above init,

SharedPreferences prefs;

Inside init method,

SharedPreferences.getInstance().then((SharedPreferences _prefs) {
      prefs = _prefs;

      setState(() {});
    });

Refer for more detail

Kaushik Bhingradiya
  • 827
  • 1
  • 13
  • 23
0

You need to wait for prefs to be initialized, then call containsKey() on it.
Ok, you have waited for prefs in adStringToSF but inside initState, you have not waited for adStringToSF, so build and adStringToSF executes concurrently.

Ehsan Askari
  • 843
  • 7
  • 19