skip to Main Content

I am trying to implement a showSnackBar on my App but I am getting this error:

Don’t use ‘BuildContext’s across async gaps.
Try rewriting the code to not use the ‘BuildContext’, or guard the use with a ‘mounted’ check.

Here is my code:

//Post reply
replyThread() async{
  setState(() { _isSubmitted = true; });
  try{
      var res = await http.post(
      Uri.parse(API.quickThreadReplyURL),
        body: {
            'post_id': _postid.toString(),
            'userID': userID.toString(),
            'sessionData': sessionData.toString(),
            'content': contentController.text,
        },
      );
      if(res.statusCode==200){
          //Clear textfield
          contentController.text = '';
          final resBody = jsonDecode(res.body);
          bool success = resBody['success'];
          if(success){
              List thread = resBody['threadList'] as List;
              setState(() {
                threadReplies = thread + threadReplies;
                _isSubmitted = false;
              });
              //Show toaster
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  backgroundColor: Color.fromARGB(255, 139, 247, 92),
                  content: 
                  Text(
                    "New thread reply successfully posted",
                    style: TextStyle(color: Colors.black),
                  ),
                )
              );
          }
          else{
            setState(() { _isSubmitted = false; });
            //Show toaster
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                backgroundColor: Color.fromARGB(255, 240, 96, 96),
                content: 
                Text(
                  "Oops! Something went wrong. Reply not posted",
                  style: TextStyle(color: Color.fromRGBO(255, 255, 255, 1)),
                ),
              )
            );
        }
      }
  }
  catch(e){
    print(e.toString());
  }
}

3

Answers


  1. You could check async logic like below:

    var res = await http.post(...);
    if (!context.mounted) return;
    if (res.statusCode == 200) {
    ...
    

    Refer the following link:
    https://dart.dev/tools/linter-rules/use_build_context_synchronously

    Login or Signup to reply.
  2. It is just a warning, but you should fix it. Because after async gaps, BuildContext maybe unmounted:

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(...);
    }
    
    Login or Signup to reply.
  3. I would like to suggest instead of passing BuildContext context in a snckbar, use the below solution which may be fix your issue of async gaps

    1.Create one snackbar_utils.dart file and add this in your existing project.

    import 'package:flutter/material.dart';
    
    class SnackbarUtil {
      static final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
    
      static void showSnackbar(String message, {Duration duration = const Duration(seconds: 2), Color backgroundColor = Colors.black}) {
        final snackBar = SnackBar(
          content: Text(message,style:TextStyle(color: Colors.white,fontSize: 12)),
          duration: duration,
          backgroundColor: backgroundColor,
        );
    
        scaffoldMessengerKey.currentState?.showSnackBar(snackBar);
      }
    
      static void showErrorSnackbar(String message, {Duration duration = const Duration(seconds: 2)}) {
        showSnackbar(message, duration: duration, backgroundColor: Colors.red);
      }
    
      static void showSuccessSnackbar(String message, {Duration duration = const Duration(seconds: 2)}) {
        showSnackbar(message, duration: duration, backgroundColor: Color(0xff96DBF8));
      }
    } 
    

    // Add this line into your MaterialApp

    MaterialApp(
      scaffoldMessengerKey: SnackbarUtil.scaffoldMessengerKey,
      ///your existing code
    )
    

    //usage :

     if(res.statusCode==200){
    //Clear textfield
    contentController.text = '';
    final resBody = jsonDecode(res.body);
    bool success = resBody['success'];
    if(success){
    ///...existing code
    //Show Snackbar
    SnackbarUtil.showSnackbar("New thread reply successfully posted",backgroundColor:Color.fromARGB(255, 139, 247, 92) );            
              }}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search