flutterblocflutter-blocrxdart

Bloc Concurrency with restartable transformer does not cancel previous event


Description

Bloc Concurrency with restartable transformer does not cancel previous event

Steps To Reproduce

The bloc file merchant_product_bloc.dart that listen on an event MerchantProductCartChanged and emit the state MerchantProductCartChange

class MerchantProductBloc extends Bloc<MerchantProductEvent, MerchantProductState> {
  MerchantProductBloc() : super(MerchantProductInitial()) {
    on<MerchantProductCartChanged>(_changeCart, transformer: restartable());
  }

  Future<void> _changeCart(
    MerchantProductCartChanged event,
    Emitter<MerchantProductState> emit,
  ) async {
    await Future.delayed(const Duration(milliseconds: 300));
    logInfo('Cart Changed | productId=${event.productId} qty=${event.qty}');
    emit(const MerchantProductCartChange.loading());
    try {
      await productRepository.changeCart(
        productId: event.productId,
        qty: event.qty,
        date: event.date,
      );
      emit(const MerchantProductCartChange.success());
    } catch (e) {
      emit(MerchantProductCartChange.error(msg: e.toString(), lastData: event));
    }
  }
}

The button I used to trigger the event MerchantProductCartChanged

BlocProvider.of<MerchantProductBloc>(context).add(
  MerchantProductCartChanged(
    productId: product.id!,
    initialQty: 1,
  ),
);

When I pressed the button 4 times very fast. It logs 4 times as well and call API 4 times

I/PLogger (30516): {PAX A920}  {Loket}  {Cart Changed | productId=104 qty=13}  {06 May 2022 08:35:58 PM}  {INFO}
I/PLogger (30516): {PAX A920}  {Loket}  {Cart Changed | productId=104 qty=14}  {06 May 2022 08:35:58 PM}  {INFO}
I/PLogger (30516): {PAX A920}  {Loket}  {Cart Changed | productId=104 qty=15}  {06 May 2022 08:35:58 PM}  {INFO}
I/PLogger (30516): {PAX A920}  {Loket}  {Cart Changed | productId=104 qty=16}  {06 May 2022 08:35:58 PM}  {INFO}

Expected Behavior

Should only logs one line at last event

I/PLogger (30516): {PAX A920}  {Loket}  {Cart Changed | productId=104 qty=16}  {06 May 2022 08:35:58 PM}  {INFO}

Solution

  • This issue was already solved on Github. The reason the bloc cannot be cancelled was because Future in Dart are truly not cancelable, as explaned here. Also the developer has provide the solution for this approach