Kennedy Owusu
Kennedy Owusu

Reputation: 6070

Undefined name 'context' after adding showDialog

I often struggle with this issue and I am hoping can help explain it to me as well as proffer a solution if necessary. The issue is with the showDialog that I have added.

I have read through other similar questions but the solutions provided are very confusing for me.

Below is an excerpt of my code

class AuthenticationController extends GetxController {
  final loginKey = GlobalKey<FormState>();
  final registerKey = GlobalKey<FormState>();
  final forgotPasswordKey = GlobalKey<FormState>();

  late TextEditingController loginEmailController,
      loginPasswordController = TextEditingController();

  late TextEditingController nameController,
      registerEmailController,
      registerPasswordController = TextEditingController();

  TextEditingController forgotPasswordEmailController = TextEditingController();

  String name = '';
  String email = '';
  String password = '';

  
  @override
  void onInit() {
    super.onInit();
    loginEmailController = TextEditingController();
    loginPasswordController = TextEditingController();
    nameController = TextEditingController();
    registerEmailController = TextEditingController();
    registerPasswordController = TextEditingController();
  }

  @override
  void onClose() {
    super.onClose();

    loginEmailController.dispose();
    loginPasswordController.dispose();

    nameController.dispose();
    registerEmailController.dispose();
    registerPasswordController.dispose();
  }

  String? validateName(String value) {
    if (value.length <= 3) {
      return kShortNameError;
    }
    return null;
  }

  String? validateEmail(String value) {
    if (!GetUtils.isEmail((value))) {
      return kInvalidEmailError;
    }
    return null;
  }

  String? validatePassword(String value) {
    if (value.length <= 6) {
      return kShortPassError;
    }
    return null;
  }

  

  Future<void> loginUser() async {
    try {
      
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => Center(
          child: CircularProgressIndicator(),
        ),
      );
      if (loginKey.currentState!.validate()) {
        loginKey.currentState!.save();
        await FirebaseAuth.instance.signInWithEmailAndPassword(
          email: loginEmailController.text.trim(),
          password: loginPasswordController.text.trim(),
        );
      }
    } on FirebaseAuthException catch (e) {
      debugPrint(e.message);
    } finally {
      
    }
  }

  Future<void> registerUser() async {
    try {
      
      if (registerKey.currentState!.validate()) {
        registerKey.currentState!.save();
        Get.offAll(BottomNavigation());
      }
    } catch (e) {
      debugPrint(e.toString());
    } finally {
      
    }
  }
}

Upvotes: 0

Views: 338

Answers (1)

Krish Bhanushali
Krish Bhanushali

Reputation: 2007

The issue is of context. And in flutter context is really important without it, it won't know where to render your circular progress indicator. There can be many approaches to solve this problem so I am open to suggestions via other people and ain't listing them all for my sake.

Since you are working with GetX, It provides an overlay context for such use cases. So you need to call dialog like this

Future<void> loginUser() async {
    try {
      
      //using Get.overlayContext
      showDialog(
        context: Get.overlayContext,
        barrierDismissible: false,
        builder: (context) => Center(
          child: CircularProgressIndicator(),
        ),
      );
      if (loginKey.currentState!.validate()) {
        loginKey.currentState!.save();
        await FirebaseAuth.instance.signInWithEmailAndPassword(
          email: loginEmailController.text.trim(),
          password: loginPasswordController.text.trim(),
        );
      }
    } on FirebaseAuthException catch (e) {
      debugPrint(e.message);
    } finally {
      
    }
  }

To close the dialog you can use bellow line wherever you find needful:

 Navigator.of(Get.overlayContext).pop();

Upvotes: 1

Related Questions