title: Flutter Bloc consumer states overlap
body: <p>I'm having some troubles with the bloc pattern, specifically with BlocConsumer reactions to the emitted states which lead to certain overlaps.
  The main character is an object list, for semplicity let's say an object with a String and int parameters.</p>
  <p>On the first page I'm adding an event to the bloc to immediately perform the list fetch:</p>
  <pre><code>ExampleBloc _exampleBloc;
  
    @override
    void initState() {
      super.initState();
      _exampleBloc = ExampleBloc()..add(FetchNewList());
    }
  </code></pre>
  <p>The layout, a grid view holding buttons with the string param as label follow by the int value, it's build by a BlocConsumer once the list is fetched:</p>
  <pre><code>BlocConsumer(
      cubit: _exampleBloc,
      builder: (context, state) {
        if (state is ListLoadingState) {
          return CircularProgressIndicator();
        } else if (state is ListLoadedState) {
          return GridView.count(
              padding: const EdgeInsets.all(20),
              crossAxisSpacing: 10,
              mainAxisSpacing: 10,
              crossAxisCount: 2,
              children: state.exampleList
                  .map((e) =&gt; FlatButton(
                        onPressed: () =&gt; _openSecondScreen(),
                        child: Text('${e.label} ${e.value}'),
                      ))
                  .toList());
        } else if (state is ListFetchErrorState) {
          return FlatButton(
              onPressed: () =&gt;
                  _exampleBloc = ExampleBloc()..add(FetchNewList()),
              child: Text('try again'));
        } else {
          return Container();
        }
      },
      listener: (context, state) {
        //will be used for other purpose 
      },
    ),
  </code></pre>
  <p>Non-blocking errors (for problems on list edit operations basically) are shown in a snackbar.
  Clicking on a button open a second page, where the same list is loaded as a ListView and some actions allows making changes on list items (for simplicity sake a tap increment the int value of 1 while a long click delete the item from the list):</p>
  <pre><code>BlocConsumer(
        cubit: _exampleBloc,
        builder: (context, state) {
          if (state is ListLoadedState) {
            return ListView.builder(
                itemCount: state.exampleList.length,
                itemBuilder: (BuildContext context, int index) {
                  var item = state.exampleList[index];
                  return ListTile(
                    onTap: () =&gt; _exampleBloc.add(UpdateItemEvent(
                        Object(item.label, item.value + 1))),
                    onLongPress: () =&gt;
                        _exampleBloc.add(DeleteItemEvent(item)),
                    title: Text(
                        '${item.label} + value: ${item.value.toString()}'),
                  );
                });
          } else {
            return Container();
          }
        },
        listener: (context, state) {
          if (state is ListUpdateErrorState) {
            Scaffold.of(context).showSnackBar(
              SnackBar(content: Text(state.errorMessage)),
            );
          } else if (state is ListUpdateInProgressState) {
            _showCircularProgressIndicator();
          }
        },
      ));
  </code></pre>
  <p>First problem: as the list is the same for both pages, I thought it would be ok to use the same bloc but, even if the last state on the first page is the &quot;ListLoadedState&quot;, once the second page is loaded the bloc builder is not building the corresponding widget. As workaround I thought to store the fetched list in a variable in the bloc class and adding an event (GetListAlreadyLoaded) in the initState of the second page to force the bloc to emit once again the ListLoadedState holding the list. Is there a better way to retrieve the last state of the bloc?</p>
  <p>Second problem: if any error occurs while performing an update/delete operations on the second page, I would like to simply show a snackbar with an error message. So in the bloc class I have something like this:</p>
  <pre><code>@override
    Stream&lt;ExampleState&gt; mapEventToState(ExampleEvent event) async* {
      //more events...
      } else if (event is PerformListUpdate) {
        yield ListUpdateInProgressState();
        //performing remote update
        var updateResult = await _repository.performUpdate(event.objectToUpdate)
        //updating local list
        if (updateResult.isSuccessful) {
          var index = exampleList.indexWhere(
              (element) =&gt; element.label == event.objectToUpdate.label);
          exampleList[index] = event.objectToUpdate;
         //triggering the bloc builder with the updated list
          yield ListLoadedState(exampleList);
        } else {
         //emit a state in order to show the error message 
          yield ListUpdateErrorState(
              &quot;An error occurred while performing update&quot;);
        }
      }
    }
  }
  </code></pre>
  <p>The problem is that if the ListUpdateErrorState is emitted the snackbar is shown, but the bloc builder is triggered by the new state and it rebuilds the widget in the else branch, which is an empty container. As a workaround I thought to first emit the ListUpdateErrorState to allow the listener function react and  show the snackbar then, soon after, emit again the ListLoadedState with the last list value in order to trigger also the builder and show again the list view. Is that okay or there's a better way to show errors?</p>
  <p>Third problem (basically the same as the second): while performing an asynchronous operation on the second page I would like to show some CircularProgressIndicator without &quot;losing&quot; the list view which could be for example in the appbar, at the bottom of the list or in the middle of the screen above the list. Emitting the &quot;ListUpdateInProgressState&quot; while starting the operation and reacting to it in the bloc listener however triggers the builder function which &quot;destroys&quot; the List view. How can I show the loading indicator without losing the list view?</p>