avoid-duplicate-bloc-event-handlers

Path
lint/correctness/avoid-duplicate-bloc-event-handlers
Default
On (recommended)
Origin
Falcon
Domain
bloc
Rule
45 of 512
recommendedbloc

Flags later registrations of the same event type in a Bloc constructor.

Bloc permits only one on<Event> handler per event type. Combine the handlers instead of registering the same event twice. This rule checks unconditional constructor registrations on this, including unqualified calls, separately for each constructor. Deferred callbacks, branches, other receivers, local on bindings, unresolved generic arguments, opaque mixins and classes overriding on are excluded. Bloc identity requires package resolution or a matching bloc/flutter_bloc import and superclass.

Bad

on<Started>((event, emit) {});
on<Started>((event, emit) {}); // A second handler for Started.

Good

on<Started>((event, emit) { initialize(); refresh(); });

Invalid

example.dartdart
import 'package:bloc/bloc.dart';

sealed class Event {}
final class Start extends Event {}
final class Stop extends Event {}
final class Reset extends Event {}

class CounterBloc extends Bloc<Event, int> {
  CounterBloc() : super(0) {
    on<Start>((event, emit) {});
    on<Start>((event, emit) {});
    this.on<Start>((event, emit) {});
    on<Stop>((event, emit) {});
    this.on<Stop>((event, emit) {});
    on<Reset>((event, emit) {});
    on<Reset>((event, emit) {});
  }
  CounterBloc.named() : super(0) {
    on<Start>((event, emit) {});
    on<Start>((event, emit) {});
  }
}
This event already has a handler. Combine the handlers into one registration.
10 on<Start>((event, emit) {});
11 on<Start>((event, emit) {});
This event already has a handler. Combine the handlers into one registration.
11 on<Start>((event, emit) {});
12 this.on<Start>((event, emit) {});
This event already has a handler. Combine the handlers into one registration.
13 on<Stop>((event, emit) {});
14 this.on<Stop>((event, emit) {});
This event already has a handler. Combine the handlers into one registration.
15 on<Reset>((event, emit) {});
16 on<Reset>((event, emit) {});
This event already has a handler. Combine the handlers into one registration.
19 on<Start>((event, emit) {});
20 on<Start>((event, emit) {});

Valid

example.dartdart
import 'package:bloc/bloc.dart';

sealed class Event {}
final class Start extends Event {}
final class Stop extends Event {}

class CounterBloc extends Bloc<Event, int> {
  CounterBloc() : super(0) {
    on<Start>((event, emit) {});
    on<Stop>((event, emit) {});
  }
  CounterBloc.named() : super(0) {
    on<Start>((event, emit) {});
  }
  CounterBloc.other(CounterBloc other) : super(0) {
    on<Start>((event, emit) {});
    other.on<Start>((event, emit) {});
  }
  CounterBloc.local(void Function<T>(Object callback) on) : super(0) {
    on<Start>((event, emit) {});
    on<Start>((event, emit) {});
  }
  CounterBloc.branch(bool flag) : super(0) {
    if (flag) {
      on<Start>((event, emit) {});
    } else {
      on<Start>((event, emit) {});
    }
  }
}

class Registry {
  Registry() {
    on<Start>(() {});
    on<Start>(() {});
  }
  void on<T>(Object callback) {}
}

class CustomBloc extends Bloc<Event, int> {
  CustomBloc() : super(0) {
    on<Start>(() {});
    on<Start>(() {});
  }
  void on<T>(Object callback) {}
}

class InheritedCustomBloc extends CustomBloc {
  InheritedCustomBloc() : super() {
    on<Start>(() {});
    on<Start>(() {});
  }
}

Configure avoid-duplicate-bloc-event-handlers

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-duplicate-bloc-event-handlers": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/avoid-duplicate-bloc-event-handlers: <reason>