Home > Mobile >  How to access bloc state properties that don't exist in the base state class?
How to access bloc state properties that don't exist in the base state class?

Time:06-05

Consider these states:

class ExerciseInitialState extends ExerciseState {}

class ExerciseLoadingState extends ExerciseState {}

class ExerciseLoadedState extends ExerciseState {
  final List<Data> data;

  const ExerciseLoadedState({required this.data});

  @override
  List<Object> get props => [data];

  // total count
  int get totalCount => data.length;
}

In the UI, I have to cast the state (ExerciseState) to ExerciseLoadedState to be able to access its property which doesn't exist in the ExerciseLoadingState and ExerciseInitialState:

final total = (context.read<ExerciseBloc>().state as ExerciseLoadedState).totalCount

It looks awkward to me to have to do this casting all the time. Is the only solution to add the same properties to the base class ExerciseState?

CodePudding user response:

It should not feel wrong to you - if you want the property to be available in all the state classes, it should be defined in the base class. E.g. you cannot get the totalCount while the state is ExerciseLoadingState simply because this property is not defined here - you need to promote the type to a specific one.

There are two possible solutions to this problem:

  1. Promote the type to ExerciseLoadedState to access the property:
return BlocBuilder<ExerciseBloc, ExerciseState>(
  builder: (context, state) {
    final totalCount = state is ExerciseLoadedState
        ? (state as ExerciseLoadedState).totalCount
        : 0;
  },
);
  1. Create an extension method on ExerciseState:
extension ExerciseStateX on ExerciseState {
  int get totalCount => this is ExerciseLoadedState
      ? (this as ExerciseLoadedState).totalCount
      : 0;
}

With the extension, you won't need to do the type promotion in your UI layer.

  • Related