Home > OS >  The await expression can only be used in an async function. Although there is async in this function
The await expression can only be used in an async function. Although there is async in this function

Time:07-10

I have an asynchronous function for checking internet access which is in another file. Here is its code:

//Check User Connection
class CheckUserConnection {

  Future checkInternetAvailability() async {
    try {
      final result = await InternetAddress.lookup('example.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        return true;
      }
    } on SocketException catch (_) {
      return false;
    }
  }
}

I need it to be activated when a button is pressed in the main menu. Here is the code for this screen:

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Example';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
        home: Container(
            child: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        // body: const MyStatelessWidget(),
              body: const MainWidget(),
      ),
    )
    );
  }
}

// class MyStatelessWidget extends StatelessWidget {
//   const MyStatelessWidget({Key? key}) : super(key: key);
class MainWidget extends StatefulWidget {
  const MainWidget({Key? key}) : super(key: key);

  @override
  State<MainWidget> createState() => _MainWidgetState();
}

class _MainWidgetState extends State<MainWidget> {

  @override
  Widget build(BuildContext context) {
    InternetDialogHandler _internetDialogHandler = InternetDialogHandler();
    CheckUserConnection _checkUserConnection = CheckUserConnection();
    bool _internetAvailable = await _checkUserConnection.checkInternetAvailability();
    // bool _internetAvailable = false;
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Column(
            children: [
              GradientButton(label: 'New Game', onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const NewGameRoute()),
                );
              }),
              GradientButton(label: 'Continue Game', onTap: () {
                if(_internetAvailable)
                {
                  //do something here;
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const NewGameRoute()),
                  );
                } else{
                  //handle no internet here
                  _internetDialogHandler.showInternetDialog(context);
                }



              }),
            ],
          ),
          Column(
            children: [
              GradientButton(label: 'Back Button', onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const BackRoute()),
                );



                // print('Button 1');



              }),
              GradientButton(label: 'Button 2', onTap: () {print('Button 2');}),
              GradientButton(label: 'Internet', onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const InternetRoute()),
                );
              }),
            ],
          )
        ],
      ),
    );
  }
}

But the problem is that when I paste:

bool _internetAvailable = await _checkUserConnection.checkInternetAvailability();

I get an error:

The await expression can only be used in an async function.

Why? Async is already in that function, which is in another file. Where else do I need to add async in my main page code?

I've been given advice:

In initstate just call a method. And in that method add async and check internrt and set state based on internet availability 

But since I'm a beginner, I don't understand what exactly I should do.

CodePudding user response:

Add an initstate to the stateful widget. Inside the initstate add this code

checkInternet();

Then define a function

checkInternet() async{
bool internetAvaibale = await _checkInternetConnection.checkInternetAvailability();
if(internetAvailable)//do something here and setstate
else // show no internet screen and setstate
}

CodePudding user response:

you called bool _internetAvailable = await _checkUserConnection.checkInternetAvailability(); in build method, In the event that build method can't async.

you must be do like below code:

class _MainWidgetState extends State<MainWidget> {
   bool? _internetAvailable;

   void checkNet() async{
   _internetAvailable = await 
   _checkUserConnection.checkInternetAvailability();
  
   // can you do any async operation into this method, Just be careful to check it
   }

  @overrider
  void initState(){
   super.initState();
   checkNet();
  }

  @override
  Widget build(BuildContext context) {
    ....
    return _internetAvailable == null?
    CupertinoActivityIndicator()//loading
    :Center(
      child: Column(
    ....

  • Related