Texter
Texter

Reputation: 169

How to move classes and functions to a separate file in Flutter/Dart?

Good day! I am new to Flutter/Dart. And the more I experiment, the bigger my main file gets. Obviously, I need a separate file in which I will store all the classes and functions that I will refer to in the future.

I have a separate screen with what I need. Here is its code:

//Internet route
class InternetRoute extends StatefulWidget {
  const InternetRoute({Key? key}) : super(key: key);

  @override
  State<InternetRoute> createState() => _InternetRouteState();
}

class _InternetRouteState extends State<InternetRoute> {
  bool ActiveConnection = false;
  String T = "";
  Future CheckUserConnection() async {
    try {
      final result = await InternetAddress.lookup('example.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        setState(() {
          ActiveConnection = true;
          T = "Turn off the data and repress again";
        });
      }
    } on SocketException catch (_) {
      setState(() {
        ActiveConnection = false;
        T = "Turn On the data and repress again";
        showInternetDialog(context);
      });
    }
  }
  @override
  void initState() {
    CheckUserConnection();
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("GeeksforGeeks"),
      ),
      body: Column(
        children: [
          Text("Active Connection? $ActiveConnection"),
          const Divider(),
          Text(T),
          OutlinedButton(
              onPressed: () {
                CheckUserConnection();
              },
              child: const Text("Check"))
        ],
      ),
    );
  }
}


//Alert Dialog about Internet connection
showInternetDialog(BuildContext context) {

  // set up the button
  Widget okButton = Center(
    child: TextButton(
      child: Text("OK"),
      onPressed: () {
        Navigator.of(context).pop(); // dismiss dialog
      },
    ),
  );

  // set up the AlertDialog
  AlertDialog alert = AlertDialog(
    // title: Text("My title"),
    content: Text("Internet connection required"),
    actions: [
      okButton,
    ],
  );

  // show the dialog
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return alert;
    },
  );

I want to create a my classes.dart file that will gradually populate with the most commonly used things. In particular, I need class _InternetRouteState and showInternetDialog.

How to transfer them to a new file? I completely copied the code of that screen. Is it correct? Would that be enough to then refer to them in main.dart (after import)? Will all their variables be visible to my screens as well?

Edit 1. I don't know how I can move CheckUserConnection to my file. I mean I took the piece of code I needed and wrapped it in the CheckUserConnection class (in my separate file), but it doesn't work. What am I doing wrong?

class CheckUserConnection {
  bool ActiveConnection = false;
  String T = "";

  Future CheckUserConnection() async {
    try {
      final result = await InternetAddress.lookup('example.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        setState(() {
          ActiveConnection = true;
          T = "Turn off the data and repress again";
        });
      }
    } on SocketException catch (_) {
      setState(() {
        ActiveConnection = false;
        T = "Turn On the data and repress again";
        // showInternetDialog(context);   //temporary
      });
    }
  }
}

The Problems tab shows the following errors:

Constructors can't have a return type.
The modifier 'async' can't be applied to the body of a constructor.
The await expression can only be used in an async function.
The method 'setState' isn't defined for the type 'CheckUserConnection'.
The method 'setState' isn't defined for the type 'CheckUserConnection'.

Upvotes: 1

Views: 2414

Answers (1)

Kaushik Chandru
Kaushik Chandru

Reputation: 17732

Create a new dart file. Name it internet_dialog_handler.dart. Add this to the file

class InternetDialogHandler{
//Alert Dialog about Internet connection
showInternetDialog(BuildContext context) {

  // set up the button
  Widget okButton = Center(
    child: TextButton(
      child: Text("OK"),
      onPressed: () {
        Navigator.of(context).pop(); // dismiss dialog
      },
    ),
  );

  // set up the AlertDialog
  AlertDialog alert = AlertDialog(
    // title: Text("My title"),
    content: Text("Internet connection required"),
    actions: [
      okButton,
    ],
  );

  // show the dialog
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return alert;
    },
  );
}

In internetRoute use this

//Internet route
class InternetRoute extends StatefulWidget {
  const InternetRoute({Key? key}) : super(key: key);

  @override
  State<InternetRoute> createState() => _InternetRouteState();
}

class _InternetRouteState extends State<InternetRoute> {
  bool ActiveConnection = false;
  String T = "";
 InternetDialogHandler _internetDialogHandler = InternetDialogHandler();
  Future CheckUserConnection() async {
    try {
      final result = await InternetAddress.lookup('example.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        setState(() {
          ActiveConnection = true;
          T = "Turn off the data and repress again";
        });
      }
    } on SocketException catch (_) {
      setState(() {
        ActiveConnection = false;
        T = "Turn On the data and repress again";
      
  //Use the variable here to access the method in that class 
_internetDialogHandler.showInternetDialog(context);
      });
    }
  }
  @override
  void initState() {
    CheckUserConnection();
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("GeeksforGeeks"),
      ),
      body: Column(
        children: [
          Text("Active Connection? $ActiveConnection"),
          const Divider(),
          Text(T),
          OutlinedButton(
              onPressed: () {
                CheckUserConnection();
              },
              child: const Text("Check"))
        ],
      ),
    );
  }
}

EDIT

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;
    }
  }
}

Use a different name for the method. Same name is used to defined the constructor of the class. Also make it work independent. Just return a true or false. Now to use this define a variable of type checkUserConnection

CheckUserConnection _checkUserConnection = CheckUserConnection();
bool _internetAvailable = await _checkUserConnection.checkInternetAvailability();
if(_internetAvailable) 
{
  //do something here;
} else{
  //handle no internet here
}

Upvotes: 1

Related Questions