Search code examples
flutterdartbloc

Bloc not triggering [builder] when emit the same state with different attributes, using equatable and props


I'm trying to add a message to a report and emitting the new state with the updated reports list, but the bloc is not triggering the rebuild even though I'm using equatable and added the reports list in the props of the ReportsLoadInProgress state.

// reports_bloc.dart

part 'reports_event.dart';
part 'reports_state.dart';

class ReportsBloc extends Bloc<ReportsEvent, ReportsState> {
  final ReportsRepository _reportsRepository;

  ReportsBloc(this._reportsRepository) : super(ReportsInitial()) {
    on<ReportsListRequested>(_OnReportsListRequested);
    on<ReportSubmitted>(_OnReportAddRequested);
    on<ReportMessageArrived>(_OnReportMessageArrived);
    on<ReportMessageSubmitted>(_OnReportMessageSubmitted);
  }


    void _OnReportMessageSubmitted(
    ReportMessageSubmitted event,
    Emitter<ReportsState> emit,
  ) async {
    // the state in this point is ReportsLoadSuccess
    final DataState dataState =
        await _reportsRepository.addMessage(event.messageData);

    if (dataState is DataSuccess) {
      List<Report> updated_reports = event.curr_reports;
      int index = updated_reports.indexWhere(
        (_element) => _element.reportId == dataState.data['reportConvId'],
      );
      updated_reports[index] = updated_reports[index].copyWith(
        messages: [
          ...updated_reports[index].messages,
          Message.fromJson(dataState.data),
        ],
      );
      emit(ReportsLoadSuccess(updated_reports));
    } else {
        //...
    }
  }

   //...

// reports_state.dart

part of 'reports_bloc.dart';

abstract class ReportsState extends Equatable {
  const ReportsState();
}

final class ReportsInitial extends ReportsState {
  @override
  List<Object> get props => [];
}

final class ReportsLoadInProgress extends ReportsState {
  @override
  List<Object> get props => [];
}

final class ReportsLoadSuccess extends ReportsState {
  final List<Report> reports;

  ReportsLoadSuccess(this.reports);

  @override
  List<Object> get props => [this.reports];
}

//...

Solution

  • Add identityHashCode(this) in the props.

    example:

    
    final class ReportsLoadSuccess extends ReportsState {
      final List<Report> reports;
    
      ReportsLoadSuccess(this.reports);
    
      @override
      List<Object> get props => [this.reports, identityHashCode(this)];
    }