简体   繁体   中英

Flutter warning message "Do not use BuildContexts across async gaps" causing application failure. I am not using stateless widget

below is the complete code, I have added the issue description before each line when the issue occurred:

class AuthService {
  //sign up user
  void signUpUser({
    required BuildContext context,
    required String email,
    required String password,
    required String name,
   }) async {
    try {
      User user = User(
        id: '',
        name: name,
        password: password,
        email: email,
        address: '',
        type: '',
        token: '',
       // cart: [],
      );
      http.Response res = await http.post(
        Uri.parse('$uri/api/signup'),
        body: user.toJson(),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
      );

      httpErrorHandle(
        response: res,
        context: context,
        onSuccess: () {
          showSnackBar(
            context,
            'Account created! Login with the same credentials!',
          );
        },
      );
    } catch (e) {
      showSnackBar(context, e.toString());
    }
  }

  // sign in user
  void signInUser({
    required BuildContext context,
    required String email,
    required String password,
  }) async {
    try {
      http.Response res = await http.post(
        Uri.parse('$uri/api/signin'),
        body: jsonEncode({
          'email': email,
          'password': password,
        }),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
      );
      //print(res.body);
     
      httpErrorHandle(
        response: res,
        context: context,
       onSuccess: () async {

          SharedPreferences prefs = await SharedPreferences.getInstance();
          //Do not use BuildContexts across async gaps.dartuse_build_context_synchronously
          Provider.of<UserProvider>(context, listen: false).setUser(res.body);
          await prefs.setString('x-auth-token', jsonDecode(res.body)['token']); 
         
 //Do not use BuildContexts across async gaps.dartuse_build_context_synchronously
            Navigator.pushNamedAndRemoveUntil(
            context,
            HomeScreen.routeName,
            (route) => false,
          );
     

        },
      );

    } catch (e) {
      showSnackBar(context, e.toString());
    }
  }
  

   // get user data
  void getUserData (
    BuildContext context,
  ) async {
    try {
       SharedPreferences prefs = await SharedPreferences.getInstance();
       String? token = prefs.getString('x-auth-token');

       if(token == null ){
        prefs.setString('x-auth-token', '');
       }

     var tokenRes = await http.post
     (Uri.parse('$uri/tokenIsValid'),
     headers: <String, String>{
       'Content-Type': 'application/json; charset=UTF-8',
       'x-auth-token': token!
     },
     );

     var response = jsonDecode(tokenRes.body);

     if(response == true){
    http.Response userRes =  await http.get
       (Uri.parse('$uri/'),headers: <String, String>{
       'Content-Type': 'application/json; charset=UTF-8',
       'x-auth-token': token
     }, );
 //Do not use BuildContexts across async gaps.dartuse_build_context_synchronously
     var userProvider = Provider.of<UserProvider>(context, listen: false);
     userProvider.setUser(userRes.body);
     }
    } catch (e) {
      showSnackBar(context, e.toString());
    }
  }
}

I am not using StatefulWidget and StatelessWidget. I have tried the below but didn't reach a solution yet:

I have used if (mounted) and I am getting this error as well The undefined name 'mounted'. Try correcting the name to one that is defined, or defining the name.

Here's what happening:

void doSomething(BuildContext context) async {
  await Future.delayed(const Duration(seconds: 1));
  // this is a crash hazard if the next call relies on the context
  // being mounted
  doSomethingElseWithContext(context);
}

You're claiming:

I have used if (mounted) and I am getting this error as well The undefined name 'mounted'. Try correcting the name to one that is defined, or defining the name.

however, you're also claiming:

I am not using StatefulWidget and StatelessWidget. I have tried the below but didn't reach a solution yet:

Currently, the mounted property is only available in the State of a StatefulWidget , so the only way to safely (in general) use a context after an async gap is to use a StatefulWidget and check the mounted property before using it. This means you will need to refactor your code if you want it to be safe and not crash if a user navigates away from your screen during a request or anything similar.
Also, you can check my other two answers on similar questions for more details:
How to check if the context is there rather than isMounted because I'm using Stateless Widget
How to prevent a Navigator.pop() in an async function from popping a route which doesn't exist anymore?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM