title: Updating toggle button using Flutter and BloC
body: <p>I'm using the youtube api and placed a favorites toggle button to fill and empty the icon depending on the state and saving them in ListView in a new page called 'favorites'. Everything is working fine in the new page as I can see the favorite Icon filled, but is not being refreshed/updated in real time in the current view. If I switch to a statefulWidget, I'm able to make it work using 'setstate', but then the changes are not reflected if I empty the icons from the favorites page.</p>
  <p>There must be something wrong in my approach as I should use the Bloc state to change both, but really stuck here. Please could you take a look at my code and give me some thoughts or ideas?</p>
  <p>Bloc File</p>
  <pre><code>class MasterBloc extends Bloc&lt;MasterEvents, MasterState&gt; {
    @override
    MasterState get initialState =&gt; MasterState.initialState();
  
    @override
    Stream&lt;MasterState&gt; mapEventToState(MasterEvents event) async* {
      if (event is MasterSetTab) {
        yield this.state.copyWith(currentTab: event.tab);
      } else if (event is MasterAddToHistory) {
        yield* _addToHistory(event);
      } else if (event is MasterRemoveFromHistory) {
        yield* _removeFromHistory(event);
      } else if (event is MasterToggleInFavorites) {
        yield* _toggleInFavorites(event);
      } else if (event is MasterLogout) {
        yield this.state.copyWith(history: [], currentTab: 0);
      }
    }
  
    Stream&lt;MasterState&gt; _addToHistory(MasterAddToHistory event) async* {
      final int index = this
          .state
          .history
          .indexWhere((item) =&gt; item.videoId == event.youtubeVideo.videoId);
  
      if (index == -1) {
        final history = List&lt;YoutubeVideo&gt;.from(this.state.history);
        history.add(event.youtubeVideo);
  
        yield this.state.copyWith(history: history);
      }
    }
  
    Stream&lt;MasterState&gt; _removeFromHistory(MasterRemoveFromHistory event) async* {
      final history = List&lt;YoutubeVideo&gt;.from(this.state.history);
      history.removeAt(event.index);
      yield this.state.copyWith(history: history);
    }
  
    Stream&lt;MasterState&gt; _toggleInFavorites(MasterToggleInFavorites event) async* {
      final int index = this
          .state
          .favorites
          .indexWhere((item) =&gt; item.videoId == event.youtubeVideo.videoId);
  
      if (index == -1) {
        final favorites = List&lt;YoutubeVideo&gt;.from(this.state.favorites);
        favorites.add(event.youtubeVideo);
        event.youtubeVideo.isFavorite = true;
  
        yield this.state.copyWith(favorites: favorites);
      } else {
        final favorites = List&lt;YoutubeVideo&gt;.from(this.state.favorites);
        favorites.removeAt(index);
        event.youtubeVideo.isFavorite = false;
  
        yield this.state.copyWith(favorites: favorites);
      }
    }
  }
  
  </code></pre>
  <p>Bloc State</p>
  <pre><code>
  class MasterState extends Equatable {
    final int currentTab;
    final List&lt;YoutubeVideo&gt; history;
    final List&lt;YoutubeVideo&gt; favorites;
  
    MasterState(
        {@required this.currentTab, @required this.history, this.favorites});
  
    static MasterState initialState() =&gt;
        MasterState(currentTab: 0, history: [], favorites: []);
  
    MasterState copyWith(
        {int currentTab,
        List&lt;YoutubeVideo&gt; history,
        List&lt;YoutubeVideo&gt; favorites}) {
      return MasterState(
          currentTab: currentTab ?? this.currentTab,
          history: history ?? this.history,
          favorites: favorites ?? this.favorites);
    }
  
    @override
    List&lt;Object&gt; get props =&gt; [currentTab, history, favorites];
  }
  
  </code></pre>
  <p>BloC Events</p>
  <pre><code>import 'package:documentales_app/models/youtube_video.dart';
  
  abstract class MasterEvents {}
  
  class MasterSetTab extends MasterEvents {
    final int tab;
  
    MasterSetTab(this.tab);
  }
  
  class MasterAddToHistory extends MasterEvents {
    final YoutubeVideo youtubeVideo;
  
    MasterAddToHistory(this.youtubeVideo);
  }
  
  class MasterRemoveFromHistory extends MasterEvents {
    final int index;
  
    MasterRemoveFromHistory(this.index);
  }
  
  class MasterToggleInFavorites extends MasterEvents {
    final YoutubeVideo youtubeVideo;
  
    MasterToggleInFavorites(this.youtubeVideo);
  }
  
  class MasterLogout extends MasterEvents {}
  
  </code></pre>
  <p>Favorites Tab</p>
  <pre><code>class FavsTab extends StatefulWidget {
    @override
    _FavsTabState createState() =&gt; _FavsTabState();
  }
  
  class _FavsTabState extends State&lt;FavsTab&gt; {
    @override
    Widget build(BuildContext context) {
      final bloc = BlocProvider.of&lt;MasterBloc&gt;(context);
      return BlocBuilder&lt;MasterBloc, MasterState&gt;(
        builder: (_, state) {
          if (state.favorites.length == 0) {
            return Center(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  SvgPicture.asset('assets/icons/empty.svg',
                      width: 50, color: Colors.greenAccent),
                  SizedBox(
                    height: 5,
                  ),
                  Text(
                    'No hay favoritos ..',
                    style: TextStyle(
                        color: Colors.greenAccent,
                        fontWeight: FontWeight.bold,
                        fontSize: 20),
                  )
                ],
              ),
            );
          }
          return ListView.builder(
            itemBuilder: (_, index) {
              final YoutubeVideo item = state.favorites[index];
              return YoutubeVideoItem(
                item: item,
                onDismissed: () {
                  bloc.add(MasterToggleInFavorites(item));
                },
              );
            },
            itemCount: state.favorites.length,
          );
        },
        condition: (prevState, newState) =&gt;
            prevState.favorites.length != newState.favorites.length,
      );
    }
  }
  </code></pre>
  <p>Home Tab where the state is called</p>
  <pre><code>class HomeTab extends StatefulWidget {
    @override
    _HomeTabState createState() =&gt; _HomeTabState();
  }
  
  class _HomeTabState extends State&lt;HomeTab&gt; {
    AccountApi _accountApi = AccountApi();
    YoutubeApi _youtubeApi = YoutubeApi(apiKey: API_KEY);
    List&lt;dynamic&gt; _users = [];
    List&lt;PlayList&gt; _playlists = [];
    List&lt;YoutubeVideo&gt; _newVideos = [];
    bool _isLoading = true;
  
    @override
    void initState() {
      super.initState();
      _load();
    }
  
    _load() async {
      final users = await _accountApi.getUsers(1);
      final List&lt;PlayList&gt; playLists =
          await _youtubeApi.getPlaylists('UCCMksip5JfLMW4AJGsjTYUA');
      final List&lt;YoutubeVideo&gt; newVideos = await _youtubeApi
          .getPlaylistVideos('PLFXLg_sVKmuujWVeOmrzsM1NnDFa8uoNk');
      setState(() {
        _users.addAll(users);
        _playlists.addAll(playLists);
        _newVideos.addAll(newVideos);
        _isLoading = false;
      });
    }
  
    @override
    Widget build(BuildContext context) {
      return ListView(
        children: [
          _isLoading
              ? HomeTabShimmer()
              : Column(
                  children: [
                    TopPlayLists(items: _playlists),
                    SizedBox(height: 10),
                    NewVideos(
                      items: _newVideos,
                    ),
                    SizedBox(height: 5),
                  ],
                )
        ],
      );
    }
  }
  
  </code></pre>
  <p>Finally the toggle button</p>
  <pre><code>CupertinoButton(
                          padding: EdgeInsets.zero,
                          minSize: 30,
                          onPressed: () {
                            masterBloc.add(MasterToggleInFavorites(item));
                          },
                          child: CircleContainer(
                            child: Icon(
                              //Icons.playlist_add,
                              item.isFavorite
                                  ? Icons.favorite
                                  : Icons.favorite_border,
                              color: Colors.white,
                            ),
                            size: 35,
                          ),
                        ),
  </code></pre>