0

I have a problem with my code: my goal is to get data from sharedprefs and use the stored data afterwards. The problem is that the function where I get the data from sharedprefs is too slow, or in other words the function where I call the function for getting the data is too fast.

The process should be: in the main.dart I call a function getDataString(), which is in the sharedPreferences.dart file, --> the function getDataString() should get the data from sharedprefs --> the data should be printed.

With my code I get as result null, but when I print the variable savedData a second time, I get the result I'm looking for. So I think that the getDataString function is simply too slow. How can I wait till the function is finished?

This is the code I tried:

This is the getDataString() function from the sharedPreferences.dart file:

Future<String> getDataString() async {
  final prefs = await SharedPreferences.getInstance();
  savedData = jsonDecode(prefs.getString("savedData"));
}

This is the initState from the main.dart:

  void initState() {
    super.initState();
    getData();
    log(savedData.toString());
    });
  }
SOS video
  • 436
  • 9
  • 21
  • 1
    GetDataString returns a future, either you need to await that or use then block – Midhun MP Dec 27 '21 at 18:21
  • and how can I do so? Sorry I'm pretty new to flutter... – SOS video Dec 27 '21 at 18:24
  • Using then: `getDataString().then( (savedData) => log(savedData.toString());)` – Midhun MP Dec 27 '21 at 18:27
  • You can check [this](https://stackoverflow.com/q/51983011/10157127) – Md. Yeasin Sheikh Dec 27 '21 at 18:29
  • @MidhunMP when I try you recomended code with the then, I still get null as result – SOS video Dec 27 '21 at 18:34
  • @SOSvideo If you use `then` it won't wait. So if you immediately print it the value will be null. If you are using it in your build method, use a future builder. If you need it in a function, then use await keyword. Check Future reference: https://api.flutter.dev/flutter/dart-async/Future-class.html – Midhun MP Dec 27 '21 at 18:50

2 Answers2

0

If all you want to do is log the data, you can move the log call to the end of getData(). If you want to use the data, you can use .then or await. For example:

getData().then((data) => log(savedData.toString())

Your method getData returns a Future. It's like a promise that sometime in the future it will return a string. It's not returning the string, just a reference that you can use to get the string in the future.

I don't have access to the rest of your class, but I suspect the getData() call should be called somewhere else and you should show a waiting widget first, not initState().

It's a little more complicated, but you can use a FutureBuilder to do that. You can find a good example here.

Paul
  • 352
  • 2
  • 3
  • I'm downvoting this answer because you should *never* perform any expensive calls from the build method, ever. I would suggest using [FutureBuilder](https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html) here. – Riwen Dec 27 '21 at 19:01
  • I agree with Riwen. I've removed the reference to build(). It could slow down rendering. The FutureBuilder is probably the best solution. – Paul Dec 27 '21 at 19:17
0

Don't try to get the future data in the initState(). Instead try Future builder in the widget build and call getData or getDataString method in future property with return value of String.

Suganya
  • 419
  • 3
  • 11