Home > Enterprise >  Flutter - Can only pop AlertDialog OR execute passed function - need to do both
Flutter - Can only pop AlertDialog OR execute passed function - need to do both

Time:05-18

TL;DR: Trying to pass a function call to a custom AlertDialog. AlertDialog needs to be popped after the function -> can't make it work.

I've created a custom AlertDialog to use throughout my app. It looks something like this:

 customAlertDialog({required context, buttonAction}){
  showDialog(context: context, builder: (context) => AlertDialog(
    title: Text("example title", style: TextStyle(color: AppTheme.colors.white),),
    content: const Text("some content"),
    actions: [
       TextButton(onPressed:  () {Navigator.of(context).pop();}, child: Text(
        "Abbrechen",
        style: TextStyle(
            color: AppTheme.colors.white),
      ),),
      TextButton(
          child: Text("do something",
            style: TextStyle(
                color: AppTheme.colors.lightRed),
          ),
          onPressed: buttonAction)
    ],
  ),);
}

The customAlertDialog takes a function call as an argument (here named buttonAction) for the last TextButtons onPressed action. It works fine when I pass:

buttonAction: () => deleteUser(context)

The problem is that this does not work in combination with a pop method. In the following only deleteUser will be called:

buttonAction: () => [deleteUser(context), Navigator.of(context).pop()]

the same if written like this:

buttonAction: () {deleteUser(context), Navigator.of(context).pop()}

I guess that the context of the customAlertDialog itself needs to be popped. So I've tried the following in the customAlertDialog (buttonAction contains () => deleteUser(context):

onPressed: () => [buttonAction, Navigator.of(context).pop()]

Now it only pops the dialog, probably because dart cannot interpret the buttonAction. So I've searched to find a way to pass only the function that should be called but wasn't successful doing so.

So my question is: How can I pass a function and still pop the dialog?

EDIT: As @SlowDeepCoder mentioned the problem could have been that the Navigator.pop() method throws the context from the stack before deleteUser() has finished and therefore it doesn't work. It was tried to be fixed with the following but it did not work:

buttonAction: () async{ await deleteUser(context); Navigator.of(context).pop(); }

CodePudding user response:

This is because you call pop() on a Navigator from an incorrect BuildContext. So instead of

buttonAction: () {
  deleteUser(context);
  Navigator.of(context).pop();
}

you have to do something like this:

buttonAction: (innerContext) {
  deleteUser(innerContext); // not sure if you need the innerContext here. Depends on your other app code
  // deleteUser(context); // use this line if the above does not work
  Navigator.of(innerContext).pop();
}

together with

TextButton(
  child: Text("do something"),
  onPressed: () => buttonAction(context),
)

I also would recommend you to give bot of your BuildContexts (customAlertDialog and showDialog) different names.

CodePudding user response:

You do not always have to use arrow function to pass a custom function.

You can simply pass the function as

buttonAction: (){
     deleteUser(context);
     Navigator.of(context).pop();
}
  • Related