Home > Back-end >  Bloc not adding widget to list?
Bloc not adding widget to list?

Time:11-30

im trying to make a list builder with bloc that adds a widget to make variants of a product, but when i press the button it wont add a new widget, it should be more clear with the images. Size is not the issue since

This is the code with the bloc builder

class MarketplaceAddServiceForm extends StatelessWidget {
  const MarketplaceAddServiceForm({
    Key? key,
    required GlobalKey<FormState> formKey,
    required this.usecase,
    required this.addServiceProvider,
  })  : _formKey = formKey,
        super(key: key);

  final GlobalKey<FormState> _formKey;
  final AddServiceUsecase usecase;
  final RegisterServiceBloc addServiceProvider;

  @override
  Widget build(BuildContext context) {
    

    return BlocConsumer<RegisterServiceBloc, RegisterServiceState>(
      listenWhen: (previous, current) {
        return current is SuccessRegisterServiceState ||
            current is ErrorRegisterServiceState;
      },
      listener: (context, state) {
        validateServiceForm(state, context);
      },
      builder: (context, state) {
        return Container(
          padding: EdgeInsets.all(ScreenUtils.percentHeight(context, 2)),
          margin: EdgeInsets.only(left: ScreenUtils.percentHeight(context, 2)),
          width: ScreenUtils.percentWidth(context, 80),
          child: SingleChildScrollView(
            child: Column(
              children: [
                Form(
                    key: _formKey,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        const VerticalSpace(),
                        const VerticalSpace(),

                        Row(children: [
                          MarketplaceAddServiceNameTextfield(
                              controller: usecase.name),
                          MarketplaceChooseTypeService()
                        ]),

                        
                        BlocBuilder<AddVariantBloc, AddVariantState>(
                          buildWhen: (previous, current) => current is VariantAddedState,
                          builder: (context, state) {
                            if(state is VariantAddedState){
                            return Column(
                              children: (List.generate(
                                state.variants.length,
                                (index) =>
                                    Container(child: state.variants[index]),
                              )),
                            );
                            } return VariantTextfield(usecase: usecase);
                          },
                        ),

                        const VerticalSpace(),
                        const VerticalSpace(),

                        MarketplaceAddProductVariantButton(),
BlocBuilder<AddVariantBloc, AddVariantState>(
                          buildWhen: (previous, current) => current is VariantAddedState,
                          builder: (context, state) {
                            if(state is VariantAddedState){
                            return Column(
                              children: (List.generate(
                                state.variants.length,
                                (index) =>
                                    Container(child: state.variants[index]),
                              )),
                            );
                            } return VariantTextfield(usecase: usecase);
                          },
                        ),

The button that should add a new one.

InkWell(
            onTap: () {
              var usecase = AddServiceUsecase();
              variants.add(VariantTextfield(usecase: usecase));
              BlocProvider.of<AddVariantBloc>(context).add(VariantAddedEvent(variants: variants ));
            
            },

blocs

class AddVariantBloc extends Bloc<AddVariantEvent, AddVariantState> {
  AddVariantBloc() : super(AddVariantInitial()) {
    on<VariantAddedEvent>((event, emit) {
      emit(VariantAddedState(variants: event.variants));
    });
  }
}


abstract class AddVariantEvent extends Equatable {
  const AddVariantEvent();

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

class VariantAddedEvent extends AddVariantEvent {

  List variants;
  VariantAddedEvent({
    required this.variants,
  });

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

}

abstract class AddVariantState extends Equatable {
  const AddVariantState();
  
  @override
  List<Object> get props => [];
}

class AddVariantInitial extends AddVariantState {}

class VariantAddedState extends AddVariantState {

  List variants;
  
  VariantAddedState({
    required this.variants,
  });

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

This is how it should work:

You press the button.

And it should add 1 more

Thank you in advance.

CodePudding user response:

Equatable properties should always be copied rather than modified. If an Equatable class contains a List or Map as properties, be sure to use List.from or Map.from respectively to ensure that equality is evaluated based on the values of the properties rather than the reference.

Equatable will see the VariantAddedState as equal each time thus the bloc will not rebuild the state, either use List.from as mentioned in their docs

i.e emit(VariantAddedState(variants: List.from(event.variants)));

or you can emit another temp State before emitting VariantAddedState

  • Related