Think_Twice
Think_Twice

Reputation: 323

How to return string with async

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

Answers (2)

Midhun MP
Midhun MP

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

HII
HII

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

Related Questions