Home > database >  Flutter BLoC screen rebulding not working
Flutter BLoC screen rebulding not working

Time:01-03

I have two functions inside my Cubit:

  void setMeatDay({required String setDay})  {
    
    emit(state.copyWith(meatDay1: setDay));


  }

  void setMeatDay2({required String setDay2})  {


    final meatDay = state.meatDay2 = setDay2;
    emit(state.copyWith(meatDay2: meatDay ));
    print(state.meatDay2);
  }

the upper one is rebuilding my UI, the "MeatDay2" not... I copied it already in the exact same way, changed it to the current state etc... Inside my state.dart I have Equatable and copywith

@override
  List<Object?> get props => [meatDay1,meatDay2];

MeatDayState copyWith({
    String? meatDay1,
    String? meatDay2,  }) {
    return MeatDayState(
      meatDay1: meatDay1 ?? this.meatDay1,
      meatDay2: meatDay2 ?? this.meatDay2,    );
  }

and for the UI I tried it with a BlocBuilder and a Listener.

 BlocBuilder<MeatDayCubit, MeatDayState>(
            builder: (context, state) {
              return BlocListener<MeatDayCubit, MeatDayState>(
                listener: (context, state) {
                  context.read<MeatDayCubit>();
                },
                child: Row(
                  crossAxisA...

What should happen: I have 7 Icons with the week days, on two I can click and mark them as "okay to eat meat" then the Icon colors changes to red. For the first function it changes, the other function changes the state in the backend but not in the front end... I have to switch screens, then it paints it correctly! I did a work around with a "setState" when I click on the Icon button like this:

 if (state.nowMeatDay2 == true) {
 BlocProvider.of<MeatDayCubit>(context).setMeatDay2(setDay2: 'Monday');
 BlocProvider.of<MeatDayCubit>(context).changeMeatDay();
                            setState(() { });
                          } 
else {
 BlocProvider.of<MeatDayCubit>(context).setMeatDay(setDay: 'Monday');
 BlocProvider.of<MeatDayCubit>(context).changeMeatDay();
    setState(() { });
                         }

then it works and paints it correctly, so it looks like that the UI rebuilding fails on the second function, but why? Reminder: My logic seems to work, I debugged it and in the backend all values and states are good, only a rebuilding is missing, but only for the second function even there is an "emit" statement.

CodePudding user response:

When you are doing

final meatDay = state.meatDay2 = setDay2;

You are first setting state.meatDay equals setDay2 that is modifying your current state. So when you use copyWith, you the current object and new object is exactly same hence no state is yield.

You should rather do

emit(state.copyWith(meatDay2: setDay2 ));

Things should work from there. One way to avoid having these kind of errors is to make the state class immutable (have all the data members declared as final in your state class). Something like,

@immutable
class FooState extends Equatable{
   final bar;
   const FooState({required this.bar});

   @override
   List<Object?> get props => [bar];
}

immutable is available with meta package.

  • Related