Moore's Lawyer
Moore's Lawyer

Reputation: 73

How to get the 'bool' value from a Future<bool> into a field variable, for later use

I am using flutter_blue package for using the Bluetooth service. I want to check whether the device has Bluetooth capabilities. The method isAvailable seems to do it. However, it returns a Future<bool>, which I am tryting to get into a variable as follows:

import 'package:flutter_blue/flutter_blue.dart';

class BT_Base {

final FlutterBlue _fb = FlutterBlue.instance;
bool BTAvailable = true;     // as a default placeholder

BT_Base () {
    BTAvailable = _fixAvail();
}

_fixAvail () async {
  return await _fb.isAvailable;
}

...

I try to get the future value from it and store into BTAvailable. Later on, I use the fixed BTAvailable field to get the appropriate Widget to be passed onto as follows:

class BTDevicePrompt extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    BT_Base bt = BT_Base();
    var btDeviceRes = bt.scan();

    if(!bt.BTAvailable) return Text('Bluetooth unavailable on device...');
    else if (btDeviceRes.isEmpty) return Text('No Bluetooth devices in range...');
    else {
      return CupertinoActionSheet(
        actions: [
                  ...
                 ],
      )
    }
  }
}

But I keep getting the error type 'Future<dynamic>' is not a subtype of type 'bool' at runtime. How can I use the Future properly in this situation? It is alright if the whole process just halts and waits for this part as well.

I have gone through a lot of solutions but I am not able to piece it together.

Upvotes: 2

Views: 4078

Answers (1)

cameron1024
cameron1024

Reputation: 10156

Any method marked async always returns a Future of some kind. You can give it an explicit return type like Future<bool> function() async { ... }, or if you leave it out it will infer Future<dynamic>.

In short, you can't get a bool from a Future<bool> outside of an async function (there are technically ways but almost certainly not what you want in Flutter).

This makes sense, since the whole point of a Future<bool> is that it's going to be a bool in the future. If there was some process to convert from a Future<bool> to a bool, what should it do if the future has not yet completed? Perhaps it should wait until it has completed. In that case, you're just describing the await keyword.

If, however, you want to use a Future in your UI in a Flutter application, you have a few options.

The simplest for your case will be to move it into initState():

class BTDevicePrompt extends StatefulWidget {
  // stateful widget boilerplate
}

class BTDevicePromptState extends State<BTDevicePrompt> {
  bool isAvailable = false;

  @override
  void initState() {
    super.initState();
    checkAvailable();  // use a helper method because initState() cannot be async
  }

  Future<void> checkAvailable() async {
    // call an async function and wait for it to complete
    bool result = await checkIfBluetoothAvailable();
    setState(() => bluetoothAvailable = result);  // set the local variable
  }

  @override
  Widget build(BuildContext context) {
    if (bluetoothAvailable) return Text('bluetooth available');
    else return Text('bluetooth not available');
  }
}

Upvotes: 5

Related Questions