galki
galki

Reputation: 8715

Delay state check inside Flutter bloc listener

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...
),

Upvotes: 2

Views: 6416

Answers (3)

Rahul Raj
Rahul Raj

Reputation: 1493

Simply use Future.delayed()

Here the sample code emit state after some delay verify its should await

if (event is LoadDataEvent) {
  emit(LoadingState());
  await Future.delayed(const Duration(seconds: 3));
  emit(SuccessState());
}

Upvotes: 0

galki
galki

Reputation: 8715

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...
),

Upvotes: 3

dubace
dubace

Reputation: 1621

You can do Future.delay() in your state is UpdatingAccount condition and check state again.

if (state is UpdatingAccount) { 
  Future.delayed(Duration(seconds: 1), (){
    if(state is "UpdatingAccount"){
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(progressSnackBar());
    }
  });
}

Upvotes: 0

Related Questions