How do I run a dialog function when a value in my provider changes to 1?

44 Views Asked by At

The standard way to show a dialog box: https://api.flutter.dev/flutter/material/showDialog.html

Instead of a button, I want to show a dialog when a variable in my provider changes from 1 to 0. My view layer widget is already using a Consumer to watch the provider variables, so how do I just trigger the dialog when the value changes?

Future<void> showStreamDialog({required BuildContext context, required String title, required String msg}) {
    return showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text(title),
            content: SingleChildScrollView(
              child: ListBody(
                children: <Widget>[
                  Text(msg),
                ],
              ),
            ),
            actions: <Widget>[
              TextButton(
                child: const Text('Ok'),
                onPressed: () {
                  context.pop();
                },
              ),
            ],
          );
        }
    );
  }
1

There are 1 best solutions below

3
jmatth On

You could use ref.listen to listen to the provider and call showDialog when the change you want occurs. Here's a simple example of a widget that does that while wrapping a widget subtree:

class DialogListener extends ConsumerStatefulWidget {
  const DialogListener({super.key, required this.child});

  final Widget child;

  @override
  ConsumerState<DialogListener> createState() => _DialogListenerState();
}

class _DialogListenerState extends ConsumerState<DialogListener> {
  bool _dialogOpen = false;

  @override
  Widget build(context) {
    ref.listen(myProvider, (prev, next) {
      if (!_dialogOpen && context.mounted && prev == 0 && next == 1) {
        _dialogOpen = true;
        showDialog(
          context: context,
          builder: (context) => const Placeholder(),
        ).then((_) {
          _dialogOpen = false;
        });
      }
    });

    return widget.child;
  }
}

The _dialogOpen is there to prevent multiple versions of the dialog from being pushed onto the navigator. It can be removed if you're sure your provider cannot continue to change values and trigger the listener again while the dialog is open.