Bloc: Refresh indicator stays loading

Created on 26 Jun 2019  路  6Comments  路  Source: felangel/bloc

Hi. First I must say thank you because the bloc package is awesome.

I'm having troubles with the refresh indicator. I follow the weather app tutorial to integrate the indicator but when I pull down to refresh, the indicator never leaves.

I think is because is getting the same data, so the state never change. I'm "completing" the completer in the bloclistener but because isn't changing state, never completes.

This is how my bloc looks:

@override
  Stream<EstablishmentState> mapEventToState(
    EstablishmentEvent event,
  ) async* {
    if (event is Fetch) {
      yield* onFetch(event);
    }
    if (event is Refresh) {
      yield* onRefresh(event);
    }
  }

  Stream<EstablishmentState> onFetch(Fetch event) async* {
    try {
      if (currentState is EstablishmentUninitialized) {
        final establishmentResult =
            await repository.getEstablishment(event.establishmentSlug);
        final addressesResult = await repository.getFacilitiesByEstablishment(
            establishmentResult.establishment.slug);
        yield* onDataLoaded(establishmentResult.establishment,
            addressesResult.addresses.toList());
      }
    } catch (_) {
      yield EstablishmentError();
    }
  }

  Stream<EstablishmentState> onRefresh(Refresh event) async* {
    try {
      final establishmentResult =
          await repository.getEstablishment(event.establishmentSlug);
      final addressesResult = await repository
          .getFacilitiesByEstablishment(establishmentResult.establishment.slug);
      yield* onDataLoaded(establishmentResult.establishment,
          addressesResult.addresses.toList());
    } catch (_) {
      yield currentState;
    }
  }

  Stream<EstablishmentState> onDataLoaded(
      Establishment establishment, List<Address> addresses) async* {
    yield EstablishmentLoaded(
        establishment: establishment, addresses: addresses);
  }

Is there a way to force to 'change' the state? Thank you.

question

Most helpful comment

@felangel you are totally right! Sorry, I wasn't passing the timestamp in the super of the EstablishmentState. Now is working.

Thank you very much for your time and help. :trophy: :tada:

All 6 comments

Hi @pblinux 馃憢
Thanks for opening an issue and for the positive feedback!

Regarding your issue, you either need to add some sort of property on the state like timestamp to ensure that the states are different across refreshes or you can just make sure your state does not extend Equatable. If the state doesn鈥檛 extend Equatable, then as long as you yield a new state instance, it will be treated as being different even though the properties might be the same.

Hope that helps and great question! 馃憤

Hi @felangel, thank you for your reply.

Removing equatable from my state worked really good, thank you. I tried with a local timestamp with DateTime and a String but stills getting true when comparing the states.

Thank you again and great work with bloc. :+1: :muscle:

No problem! The timestamp approach should have worked as well. If you want to debug that further please let me know 馃憤

Thanks, of course. I tried again, but still gets true when comparing.

This is how I'm handling the data after refresh:

Stream<EstablishmentState> onDataLoaded(
      Establishment establishment, List<Address> addresses) async* {
    final newState = EstablishmentLoaded(
        establishment: establishment,
        addresses: addresses,
        timestamp: DateTime.now().toString());
    if (currentState is EstablishmentLoaded) {
      print(newState == currentState);
      print((currentState as EstablishmentLoaded).timestamp);
      print(newState.timestamp);
    }
    yield newState;
  }

And the result of that.

I/flutter ( 3695): true
I/flutter ( 3695): 2019-06-26 12:11:53.261730
I/flutter ( 3695): 2019-06-26 12:11:57.453405

The timestamps are different but comparing always gets true :thinking:
Could be a Equatable issue?

@pblinux can you share the code for the EstablishmentState class? My guess is you're not passing the timestamp to the superclass like:

class EstablishmentState extends Equatable {
  ...
  final String timestamp;

  EstablishmentState({..., @required this.timestamp}) : super([..., timestamp]);
}

@felangel you are totally right! Sorry, I wasn't passing the timestamp in the super of the EstablishmentState. Now is working.

Thank you very much for your time and help. :trophy: :tada:

Was this page helpful?
0 / 5 - 0 ratings