How do I convert 'Future<String?>' to 'Future<String>?' in Flutter?

Issue

So basically Iam working with the network_info_plus package to read the current connected Wifiname of the device. I want to use a FutureBuilder to get the future from await info.getWifiName();. The problem is that the method returns a Future<String?>. What is the smartest way to convert this to Future<String>??

e.g.

    NetworkInfo info = NetworkInfo();
    ...
    FutureBuilder<String>(
    future: info.getWifiName(), // Error: The argument type 'Future<String?>' 
                                // can't be assigned to the parameter type 'Future<String>?'
    builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        ...

Solution

If you look at the internal implementation of the getWifiName() function

  /// Obtains the wifi name (SSID) of the connected network
  ///
  /// Please note that it DOESN'T WORK on emulators (returns null).
  ///
  /// From android 8.0 onwards the GPS must be ON (high accuracy)
  /// in order to be able to obtain the SSID.
  Future<String?> getWifiName() {
    return _platform.getWifiName();
  }

It returns a Future<String?> . You have two options here when it comes to your FutureBuilder

Here is a demo of the default flutter app running this code on a mac app

enter image description here

You can either call it this way

FutureBuilder<String?>(
      future: info.getWifiName(),
      builder: (context, snapshot) {
        if (snapshot.hasData &&
            snapshot.connectionState == ConnectionState.done) {
          return Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'You are connected to WIFI ',
                ),
                Text(
                  '${snapshot.data}',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          );
        }
        return const Center(
          child: CircularProgressIndicator(),
        );
      })

or you can choose to not explicitly declare a data type when using FutureBuilder

FutureBuilder(
      future: info.getWifiName(),
      builder: (context, snapshot) {
        if (snapshot.hasData &&
            snapshot.connectionState == ConnectionState.done) {
          return Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'You are connected to WIFI ',
                ),
                Text(
                  '${snapshot.data}',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          );
        }
        return const Center(
          child: CircularProgressIndicator(),
        );
      })

Note that you aren’t really converting the data type here, merely stating it and making the FutureBuilder aware of what data type to expect from the given future.

Answered By – Vipin Kumar Kashyap

Answer Checked By – Mildred Charles (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.