Reputation: 323
I am struggling to return a string value from a async method.
Here is my utilities class:
class Utilities {
Future<PackageInfo> getPackageInfo() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
return packageInfo;
}
String getVersion() {
String version;
getPackageInfo().then((PackageInfo pi) {
version = pi.version;
});
return version;
}
}
Here is my UI where I call the getVersion method:
class abc extends StatelessWidget {
Utilities _utilities = new Utilities();
@override
Widget build(BuildContext context) {
...
Text(_utilities.getVersion()),
...
}
I am always getting a null value error at the Text() widget.
What am I doing wrong?
Upvotes: 0
Views: 847
Reputation: 107121
Your code in the getVersion method executes asynchronously. Means the function will return way before your then clause is called/executed, thus it returns a null value and result in a null value error.
If your UI is dependent on a Future use FutureBuilder. Replace your Text widget with the following code:
FutureBuilder<String>(
future: getVersion(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data);
} else if (snapshot.hasError) {
return Text('Oh no!!!');
} else {
return CircularProgressIndicator()
},
},
),
And change your getVersion method like:
Future<String> getVersion() async {
PackageInfo pi = await getPackageInfo();
return pi.version;
}
Upvotes: 1
Reputation: 4109
You are returning normal String
while you should wrap that in a Future
:
Future<String> getVersion() async => getPackageInfo().then((PackageInfo pi) => pi.version);
and the Text
widget becomes:
FutureBuilder<String>(
future: getVersion(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if(snapshot.connectionState==ConnectionState.waiting)
return CircularProgressIndicator();
else if(snapshot.connectionState==ConnectionState.done && snapshot.hasData)
return Text(snapshot.data);
//handle other connection statuses
}
),
Upvotes: 1