Adding to list with Bloc (flutter)
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));
}
Kamand Shayegan
Updated on January 04, 2023Comments
-
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 about 2 yearsThis was the exact issue. Now it works. Thanks.
-
Tom Sitter about 2 yearsGlad to help! Can you please select my answer as accepted?
-
Kamand Shayegan about 2 yearsDidn't I accept it? I think I did. The green tick is on.