Faabass
Faabass

Reputation: 1164

How to wait for async in initState

I have an async function that needs to be called in initState in an Stateful widget, but I cannot use await as initState is not async.

sendHealthData is async as it get some information from the Health Api, and then I need to send that information to HomeSubScreen which is another StatefulWidget. But at the time the HomeSubScreen is created, the sendHealthData method didn't get all the information, so If I try to send some value in a param to the HomeSubScreen, the value will be null.

How can I do that?

@override
  void initState() {
    super.initState();
    sendHealthData();
    _widgetOptions = <Widget>[
      HomeSubScreen(healthData),
    ];

  }

Update: If I added a then() I get the following error:

NoSuchMethodError: The method 'elementAt' was called on null.

Code Updated:

@override
      void initState() {
        super.initState();
        sendHealthData().then((response){
             _widgetOptions = <Widget>[
                 HomeSubScreen(healthData),
              ];
        });


      }

Upvotes: 13

Views: 16361

Answers (3)

Ravinder Kumar
Ravinder Kumar

Reputation: 7990

You can also use FutureBuilder

FutureBuilder<String>(
  future: getYourDataFromApi(), 
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    switch (snapshot.connectionState) {
      case ConnectionState.none:
        return Text('start widget');
      case ConnectionState.active:
      case ConnectionState.waiting:
        return Text('Awaiting result from api...');
      case ConnectionState.done:
        if (snapshot.hasError)
          return Text('Error: ${snapshot.error}');
        return Text('Result: ${snapshot.data}');
    }
    return null; // unreachable
  },
)

Upvotes: 7

Cristian Bregant
Cristian Bregant

Reputation: 1906

You cannot await for async function in the initState, but a little trick is to use the Then keyword to execute code after that future complete.

eg:

@override


void initState() {
    super.initState();
    sendHealthData().then((response){

      _widgetOptions = <Widget>[
        HomeSubScreen(response),
      ];

    });


  }

and the function must be like:

Future sendHealthData() async{}

Upvotes: 6

CopsOnRoad
CopsOnRoad

Reputation: 267584

I'm giving you general idea of it.

@override
void initState() {
  super.initState();

  function().then((int value) {
    // future is completed you can perform your task 
  });

  function2(); // or you can simply call the method if you don't want anything to do after future completes
}

Future<int> function() async {
  // do something here 
}

Future<int> function2() async {
  // do something here
}

Upvotes: 12

Related Questions