Reputation: 1164
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
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
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
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