Home > OS >  How do I fix "Do not use BuildContexts accros async gaps" when using Snack Bar and Navigat
How do I fix "Do not use BuildContexts accros async gaps" when using Snack Bar and Navigat

Time:01-01

This is my code


  _signinRouter(
    userId,
    BuildContext context, {
    phone = false,
    email = false,
    googleSignUp = false,
    userData,
  }) async {
    NetworkController network = NetworkController();

    setState(() {
      _isLoading = true;
    });

    CallResponse response = await network.fetchUserData(
      userId,
      phone: phone,
      email: email,
    );

    setState(() {
      _isLoading = false;
    });
    if (response.status == 1) {
      debugPrint(response.msg.toString());
      //IF USER DATA IS FOUND

      showSnackBar('User account exists', context);
    } else {
      //Since network returns one or zero, 1 for the success of request and 0 for both server error and failure of request
      //Response msg will return null if user was not found and it will return an actual server failure msg if it was a server error
      if (response.msg == 'null') {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => (googleSignUp)
                ? GooglePostSignUp(userData: userData)
                : ServerSignUp(phoneNumber: userId, userData: userData),
          ),
        );
      } else {
        showSnackBar(response.msg, context);
      }
    }
  }
}

I am calling the function within a stateful widget and I defined a function to help in calling the snack bar, my app relies heavily on snack bars and I have this same error all across my files. This is the snack bar function

void showSnackBar(String? value, BuildContext context) {
  ScaffoldMessenger.of(context).hideCurrentSnackBar();
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      content: Text(
        value!,
        style: p2(
          false,
        ),
      ),
      duration: const Duration(seconds: 2),
      action: SnackBarAction(
        label: 'Close',
        textColor: themeColor,
        onPressed: () {
          ScaffoldMessenger.of(context).hideCurrentSnackBar();
        },
      ),
    ),
  );
}

I can call the my custom snack bar from anywhere with in my project easily.

I can trick the IDE and lint by removing the Buildcontext type in the function but it not practical, i can check if the widget is mounted before calling the snackbar but i dont think it is very practical ???

CodePudding user response:

the simplest way is just put

if (!mounted) return;

for void functions before you call snackbar.

CodePudding user response:

I know you are thinking of app performance in mind, Oh! wait! flutter already did that for you :). You don't need to work around it except if you have time and energy. Note that, the context has to be passed every time and so checking the context mount every time is not "i don't think it is very practical" situation

Things like this I call (The warning error). When working with async functions within a context that is likely to be lost due to nesting. You need to handle it with care.

One way to do that is by checking for the widget-mounted state. basically, Don't use context after async if you're not sure your widget is mounted.

To be sure use the following:

if (!mounted) return; // check before calling `Navigator`
Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => (googleSignUp)
                ? GooglePostSignUp(userData: userData)
                : ServerSignUp(phoneNumber: userId, userData: userData),
          ),
        );

To make the code short-hand just do the normals!!! :) break the code down in the same file!!

Bye.

  • Related