# on<E extends Event> method Null safety

void on<E extends Event>(

1. EventHandler<E, TutorialFormState> handler,
2. {EventTransformer<E>? transformer}

)
inherited

Register event handler for an event of type `E`. There should only ever be one event handler per event type `E`.

    abstract class CounterEvent {}
    class CounterIncrementPressed extends CounterEvent {}

    class CounterBloc extends Bloc<CounterEvent, int> {
      CounterBloc() : super(0) {
        on<CounterIncrementPressed>((event, emit) => emit(state + 1));
      }
    }

- A StateError will be thrown if there are multiple event handlers registered for the same type `E`.

By default, events will be processed concurrently.

See also:

- `EventTransformer` to customize how events are processed.
- package:bloc_concurrency for an opinionated set of event transformers.

## Implementation

    void on<E extends Event>(
      EventHandler<E, State> handler, {
      EventTransformer<E>? transformer,
    }) {
      // ignore: prefer_asserts_with_message
      assert(() {
        final handlerExists = _handlers.any((handler) => handler.type == E);
        if (handlerExists) {
          throw StateError(
            'on<$E> was called multiple times. '
            'There should only be a single event handler per event type.',
          );
        }
        _handlers.add(_Handler(isType: (dynamic e) => e is E, type: E));
        return true;
      }());

      final subscription = (transformer ?? _eventTransformer)(
        _eventController.stream.where((event) => event is E).cast<E>(),
        (dynamic event) {
          void onEmit(State state) {
            if (isClosed) return;
            if (this.state == state && _emitted) return;
            onTransition(
              Transition(
                currentState: this.state,
                event: event as E,
                nextState: state,
              ),
            );
            emit(state);
          }

          final emitter = _Emitter(onEmit);
          final controller = StreamController<E>.broadcast(
            sync: true,
            onCancel: emitter.cancel,
          );

          Future<void> handleEvent() async {
            void onDone() {
              emitter.complete();
              _emitters.remove(emitter);
              if (!controller.isClosed) controller.close();
            }

            try {
              _emitters.add(emitter);
              await handler(event as E, emitter);
            } catch (error, stackTrace) {
              onError(error, stackTrace);
              rethrow;
            } finally {
              onDone();
            }
          }

          handleEvent();
          return controller.stream;
        },
      ).listen(null);
      _subscriptions.add(subscription);
    }