How to initialize a Future and then replace it in Flutter/Dart?

Viewed 151

How do I do the initialize the Future correctly for a FutureBuilder in Flutter? As you can see, there is an exception being thrown because the late Future is not yet initialized. (please ignore that parameter v is not used in the method, removed method details for simplicity, but v is important).

late Future<int> myIntvalue;

Future<int> getStackInit(int v) async {
  await Future.delay(Duration(seconds: 5));
  return 5;
}

@override
void initState()
{
  SharedPreferences.getInstance().then((sp) {
       int value = sp.getInt("StartValue") ?? 0;
       myIntvalue = getStackInit(value);
  });
  super.initState();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
      body: FutureBuilder(
            future: myIntvalue,     <-- Exception, not initialized
            builder: (context, AsyncSnapshot snapshot) {
              ....

The problem ist, that myIntvalue is not yet initialized when the FutureBuilder is reached. What is the best way to initialized the future before it is "really" initialized? Or is it possible to define a future during initialization and "replace" the result later on? Is there any more elegant way?

Thanks!

1 Answers

In general, if you need to be able to check if something's been initialized, you need to make it nullable.

Or you could set your Future to an initial sentinel value (e.g. Future.value(0)), replace it later, and call setState to rebuild your widget tree, just as you would if you had to update any other member variable.

However, in your case you should just initialize myIntvalue to the desired Future as soon as possible. For example:

@override
void initState()
{
  Future<int> initializeIntValue() async {
    var sp = SharedPreferences.getInstance();
    int value = sp.getInt("StartValue") ?? 0;
    return await getStackInit(value);
  }

  myIntvalue = initializeIntValue();
  super.initState();
}
Related