Adding to list with Bloc (flutter)

1,371

Solution 1

Your StudentHandlerState isn't adding the new list of items to it's internal badSts variable so when you emit the new state nothing is updated. Try the following.

class StudentHandlerState {
  ///Sts = Students
  List<String> badSts;
  StudentHandlerState({required this.badSts});
}

Using this.badSts assigns the passed in parameter to the badSts variable.

Solution 2

Also I noticed that you are changing the list directly from states. Ideally, states are immutable. Store the values from the state in a separate variable and then add/remove items.

You can do this:

void removeFromBadSts(String name){
  final list = state.badSts;
  list.removeWhere((element) => element==name);
  return emit(StudentHandlerState(badSts: list));
}

Instead of this:

void removeFromBadSts(String name){
  state.badSts.removeWhere((element) => element==name);
  return emit(StudentHandlerState(badSts: state.badSts));
}
Share:
1,371
Kamand Shayegan
Author by

Kamand Shayegan

Updated on January 04, 2023

Comments

  • Kamand Shayegan
    Kamand Shayegan over 1 year

    I've just started learning how to manage state with BLOC in flutter. I've written this small and simple example (With Cubit) that is supposed to add names to a list and remove from it. The list does not get filled and I cannot figure out where the problem is.

    My code:

    class StudentHandlerCubit extends Cubit<StudentHandlerState> {
      ///initial value is set here:
      StudentHandlerCubit() : super(StudentHandlerState(badSts: []));
    
      addToBadSts(String name) {
        state.badSts.add(name);
        return emit(StudentHandlerState(badSts: state.badSts));
      }
    
      void removeFromBadSts(String name){
        state.badSts.removeWhere((element) => element==name);
        return emit(StudentHandlerState(badSts: state.badSts));
      }
    
    }
    
    class StudentHandlerState{
      ///Sts = Students
      List<String> badSts = [];
      StudentHandlerState({badSts=const []});
    }
    

    Here is the ui: (Elevated Button to add and remove)

    class CustomElevatedButton extends StatelessWidget {
      final ButtonState buttonState;
      final GlobalKey<FormState> globalKey;
      final TextEditingController controller;
    
      const CustomElevatedButton({Key? key,
        required this.buttonState,
        required this.globalKey,
        required this.controller})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        var blocModel = context.read<StudentHandlerCubit>();
        return ElevatedButton(
          style: ElevatedButton.styleFrom(
              primary: buttonState == ButtonState.add ? Colors.green : Colors.red),
          onPressed: () {
            if (globalKey.currentState!.validate()) {
              _onPressed(context, buttonState, controller);
              // Navigator.pop(context);
            }
          },
          child: Text(_setText(buttonState)),
        );
      }
    
      void _onPressed(BuildContext ctx, ButtonState bs,
          TextEditingController cntr) {
        var blocModel = ctx.read<StudentHandlerCubit>();
        bs == ButtonState.add ?
        blocModel.addToBadSts(cntr.text) :
        blocModel.removeFromBadSts(cntr.text);
    
      }
      String _setText(ButtonState bs) {
        return bs == ButtonState.add ?
        'add' : 'delete';
      }
    
    }
    

    And here is the column which I want to show all the names:

    Column(
                      children: [
                        const Text(header1),
                        const Divider(
                          thickness: 2,
                        ),
                        BlocBuilder<StudentHandlerCubit,
                            StudentHandlerState>(
                            builder: (context, handler) {
                              return Column(
                                  children: handler.badSts
                                      .map((e) => Text(e))
                                      .toList());
                            })
                      ],
                    ),
    

    This codebase does not work. Thanks for helping.

  • Kamand Shayegan
    Kamand Shayegan about 2 years
    This was the exact issue. Now it works. Thanks.
  • Tom Sitter
    Tom Sitter about 2 years
    Glad to help! Can you please select my answer as accepted?
  • Kamand Shayegan
    Kamand Shayegan about 2 years
    Didn't I accept it? I think I did. The green tick is on.