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(
....