4

I have the follwing Bloc

class DeviceBloc extends Bloc<DeviceEvent, DeviceState> {
  DataRepository repository;

  DeviceBloc({@required this.repository}) : super(DeviceInitialState()) {
    on<FetchDevicesEvent>(onFetchResources);
  }

  Future<void> onFetchResources(
      FetchDevicesEvent event, Emitter<DeviceState> emit) async {
    emit.call(DeviceLoadingState());

    try {
      List<DeviceResource> devices = await repository.getResources(event.type);
      emit.call(DeviceLoadedState(devices: devices));
    } catch (e) {
      emit.call(DeviceErrorState(message: e.toString()));
    }
  }
}

When FetchDevicesEvent event is triggered it starts a long running task, if additional FetchDevicesEvent events are recieved before the running task is completed the wrong result are returned to the caller. How can I suspend the awaited task and always start a new as soon as a new FetchDevicesEvent is recieved?

Marc
  • 2,023
  • 4
  • 16
  • 30

1 Answers1

7

Found the solution myself by using transformer: restartable() from bloc_concurrency package

class DeviceBloc extends Bloc<DeviceEvent, DeviceState> {
  DataRepository repository;

  DeviceBloc({@required this.repository}) : super(DeviceInitialState()) {
    on<FetchDevicesEvent>(
      onFetchResources,
      transformer: restartable(),
    );
  }

  Future<void> onFetchResources(
      FetchDevicesEvent event, Emitter<DeviceState> emit) async {
    emit.call(DeviceLoadingState());

    try {
      final List<DeviceResource> devices =
          await repository.getResources(event.type);
      emit.call(DeviceLoadedState(devices: devices));
    } catch (e) {
      emit.call(DeviceErrorState(message: e.toString()));
    }
  }

}

Marc
  • 2,023
  • 4
  • 16
  • 30