0

I've made a login form with cognito in flutter, and I wanna notify the users after a successful or failed attempt to login, with a AlertDialog. After a user failed attempt, the dialog displays, it pops back to the current screen, and after I press the button in the alert dialog (OK), it throws and error Looking up a deactivated widget's ancestor is unsafe. I don't understand quite why is this happening, I'm new to flutter so not sure how to solve it. This the login method:

 void loginToCognito() async {
    final storage = FlutterSecureStorage();
    await storage.write(key: "e", value: email);
    await storage.write(key: "p", value: password);
    String message;
    try {
      _user = await _userService.login(email, password);
      message = 'User successfully logged in!';
      if (!_user.confirmed) {
        message = 'Please confirm user account';
      }
      return showAlertDialog(
        context,
        message,
        Navigator.pushNamed(context, SecondScreen.id),
      );
    } on CognitoClientException catch (e) {
      if (e.code == 'InvalidParameterException' ||
          e.code == 'NotAuthorizedException' ||
          e.code == 'UserNotFoundException' ||
          e.code == 'ResourceNotFoundException') {
        message = e.message;
/// This is where the error happpens 
        return showAlertDialog(
          context,
          message,
          Navigator.pop(context),
        );
      } else {
        message = 'An unknown client error occurred';
        return showAlertDialog(
          context,
          message,
          Navigator.pop(context),
        );
      }
    } catch (e) {
      message = 'An unknown error occurred';
      return showAlertDialog(
        context,
        message,
        Navigator.pop(context),
      );
    }
  }

And here is the alertDialog:

showAlertDialog(
  BuildContext context,
  String message,
  void function,
) {
  // Create button
  Widget okButton = FlatButton(
    child: Text("OK"),
    onPressed: () {
      Navigator.of(context).pop();
    },
  );

  // Create AlertDialog
  AlertDialog alert = AlertDialog(
    title: Text('User Login'),
    content: Text(message),
    actions: [
      okButton,
    ],
  );

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

Is this error because the first Navigator.pop(context); happened? If so, what is the best approach to fix this issue? Thanks in advance. I've tried with the final globalScaffoldKey = GlobalKey<ScaffoldState>(); but failed to fix the issue with it.

GrandMagus
  • 600
  • 3
  • 12
  • 37

1 Answers1

0

You are never using the function inside your showAlertDialog(), but I see what you are trying to accomplish here, so let me explain:

Don't set the function equal to Navigator.pop..., instead check whether the function is null in you FlatButton and then call Navigator.pop... If it is not null, then the FlatButton should call the function you gave as an argument.

You are also popping from the wrong context, let me rename your variables:

showAlertDialog(
  BuildContext contextFromCall, //this context is an argument you specified
  String message,
  void function,
) {
  // Create button
  Widget okButton = FlatButton(
    child: Text("OK"),
    onPressed: () {
      Navigator.of(contextFromCall).pop(); //here you pop that context
    },
  );
...
}

However, you show the AlertDialog with a different context:

showDialog(
    context: contextFromCall,
    builder: (BuildContext contextInsideDialog) { //you should pop this one
      return alert;
    },
  );

So the solution is to pass the contextInsideDialog to your alert, then pass it on to your okButton, where you should call Navigator.pop with that context

Lars
  • 1,250
  • 9
  • 25
  • I renamed the variables like you, still getting the same error, am I getting this wrong? Should I change the return statement in the `loginToCognito()`? When a user missed the pass, he triggers the `showAlertDialog()`, that has 3 arguments, context, message and third being the void function `Navigator.pop()`. So it does the pop from the void function, but when you `pop()` the context again with the `OK` button from `showAlertDialog()`, the errors is still there. From my understanding, it is because it doesn't have a widget to pop to since we dispose it in the `loginToCognito()`, right? – GrandMagus Mar 04 '21 at 17:50