bloc icon indicating copy to clipboard operation
bloc copied to clipboard

fix: BlocBuilder doesn't receive state when emitted from async loop

Open Seferi opened this issue 7 months ago • 1 comments

Description Hi there, I'm facing this issue where the state (RefreshedContactCount) is emitted but for some reason not being received by the BlocBuilder. All the other states are received and updating the UI just fine but RefreshedContactCount. Here is the method in the cubit which emits the state:


Future<void> refreshAllContacts() async {
    bool hasInternet = await InternetConnection().hasInternetAccess;
    if (!hasInternet) {
      emit(RefreshAllContactsFailure());
    } else {
      int refreshedContactsCount = 0;
      List<ProfileModel> contacts = getIt<UserCubit>().keyoxideUser.contacts;

      for (ProfileModel contact in contacts) {
        emit(RefreshingAllContacts());
        bool isContactRefreshed = await refreshContact(contact: contact, isRefreshingAllContacts: true);
        if (isContactRefreshed) {
          refreshedContactsCount++;
          emit(RefreshedContactCount(successfulRefreshCount: refreshedContactsCount));
        }
      }
      emit(RefreshAllContactsSuccess());
    }
  }

And this is the BlocBuilder which is suppose to receive the state:

BlocBuilder<ContactsCubit, ContactsState>(
  bloc: getIt<ContactsCubit>(),
  builder: (context, state) {
    if (state is RefreshingAllContacts) {

    }
    if (state is RefreshedContactCount) {
      refreshedContactCount = state.successfulRefreshCount;
    }
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 20.0),
      child: Center(
        child: Container(
            width: double.infinity,
            height: 200,
            decoration: BoxDecoration(
                color: Theme.of(context).brightness == Brightness.dark
                    ? Colors.black.withOpacity(0.9)
                    : Colors.white.withOpacity(0.9),
                borderRadius: const BorderRadius.all(Radius.circular(20))),
            child: Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const CircularProgressIndicator(),
                        const SizedBox(height: 10),
                        Text("contacts_refresh_all_count".localizeWithPlaceholders(
                              [refreshedContactCount.toString(), totalContactCount.toString()])!,
                          textAlign: TextAlign.center,
                        ),
                      ],
                    )
            )),
      ),
    );
  },
);

Expected Behavior State gets received by the BlocBuilder or Consumer and updates the UI.

Additional Context I have been using Bloc for years now and never faced this kind of issue, I'm guessing the loop might be causing the issue, causing some kind of race condition. I'd very much appreciate if someone could help or take a look. Thanks.

Seferi avatar Jun 27 '24 16:06 Seferi