Delay state check inside Flutter bloc listener

Issue

I’m sending data to the server via a bloc and showing a progressSnackBar during, and then a successSnackBar on success. Sometimes this takes less than a second and it makes sense to not show the progressSnackBar at all – in other words wait a second and then check if the state is still UpdatingAccount. I’ve tried and failed with different combinations involving Future.delay(...) and I can probably do a setState hack but is there a way to achieve this just inside the bloc listener?

BlocListener<AccountBloc, AccountState>(
  listener: (BuildContext context, state) {
    if (state is UpdatingAccount) { // <-- delay this
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(progressSnackBar());
    } else if (state is AccountUpdated) {
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(successSnackBar());
    }
  },
  // rest...
),

Solution

I ended up making the widget stateful and giving it an _updated bool member.

BlocListener<AccountBloc, AccountState>(
  listener: (BuildContext context, state) {
    if (state is UpdatingAccount) {
      _updated = false;
      Future.delayed(Duration(seconds: 1), () {
        if (!_updated) {
          Scaffold.of(context)
            ..hideCurrentSnackBar()
            ..showSnackBar(progressSnackBar());
        }
      });
    } else if (state is AccountUpdated) {
      _updated = true;
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(successSnackBar());
    }
  },
  // rest...
),

Answered By – galki

Answer Checked By – Gilberto Lyons (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *