Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Flutter Issue: Either zero or 2 or more [DropdownMenuItem]s were detected with the same value

I know, It is asked many time but none of the solution is working.

There is a bank list in first drop down, On bank selection an api is being called for branch in second drop down after selection of branch for first time it is working fine, When bank is changed again api is being called to get branch of respective bank that time issue is coming because already selected branch has value, I’m trying to clear previous selected value of branch and making list empty before populating branch. Issue is coming because branch area is same in other bank also but branch id is unique. when branch list is empty or not having same branch area that time there is no issue.

I tried to "overrried" method for comparing branch but not working

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

this is model class for branch.

class Branch {
  final int? bankId;
  final int? branchId;
  final String? ifscCode;
  final String? descriptionEn;
  final dynamic descriptionLl;
  
  Branch({
    this.bankId,
    this.branchId,
    this.ifscCode,
    this.descriptionEn,
    this.descriptionLl,
  });

  factory Branch.fromJson(Map<String, dynamic> json) => Branch(
        bankId: json["bank_id"],
        branchId: json["branch_id"],
        ifscCode: json["ifsc_code"],
        descriptionEn: json["description_en"],
        descriptionLl: json["description_ll"],
      );
  
  @override
  String toString() {
    return descriptionEn.toString();
  }
  @override
  bool operator ==(dynamic other) {
    return other != null && branchId == other.branchId &&
        descriptionEn == other.descriptionEn;
  }
}

After getting state change of branch making previous selected branch null

else if (state is GetBranchSuccessState) {
            
            selectedBranch = null;
            ifsc = null;
            branchList=[];
            branchList = state.data.data!;

          } 

Whenever choosing same bank as i firstly selected getting no issue it seems selected value is getting store?

My Widget

 BlocConsumer<InternalRegistrationBloc, InternalRegistrationState>(
        listener: (context, state) {
          if (state is GetBankSuccessState) {
            dismissProgress();
          } else if (state is GetBranchSuccessState) {
            dismissProgress();
          }
        },
        builder: (context, state) {
          if (state is GetBankSuccessState) {
            bankList = state.data.data!;
          } else if (state is GetBranchSuccessState) {
            selectedBranch = null;
            ifsc = null;
            branchList = [];
            branchList = state.data.data!;
          }
          return Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Form(
                key: _gformKey,
                child: Column(
                  children: [
                    QDropDownList(
                      title: 'Bank name',
                      dropdownList: bankList,
                      selectedItem: selectedBank,
                      isMandatory: isBankUser,
                      onChanged: (value) {
                        selectedBank = value;
                        if (selectedBank != null) {
                          bloc.add(BranchEvent(selectedBank!.bankId!));
                        }
                      },
                    ),
                    QDropDownList(
                      title: 'Branch name',
                      dropdownList: branchList,
                      selectedItem: selectedBranch,
                      isMandatory: isBankUser,
                      onChanged: (value) {
                        selectedBranch = value;
                        bloc.add(
                            SetIFSCCodeEvent(selectedBranch!.ifscCode!));
                      },
                    )
                  ],
                ),
              ),
            ],
          );
        },
      ),



 

In Image, bank of india getting issue because branch list contain the same branch ares name as Axis Bank contain, It has no issue when i select Bank of rajshthan becuase it has no branch list. when selecting Axis Bank bank getting no issue and getting old value.

Custom drop down

import 'package:flutter/material.dart';


class QDropDownList extends StatefulWidget {
  final ValueChanged<dynamic> onChanged;
  final List<dynamic> dropdownList;
  final dynamic selectedItem;
  final bool isTitleAbove;
  final String title;
  final bool isMandatory;
  final String dropDownHint;
  final Icon arrowIcon;

  const QDropDownList(
      {super.key,
      required this.onChanged,
      required this.dropdownList,
      required this.selectedItem,
      this.isTitleAbove = true,
      this.title = 'Title',
      this.isMandatory = true,
      this.dropDownHint = 'Select',
      this.arrowIcon = const Icon(
        Icons.keyboard_arrow_down,
        size: 15,
      )});

  @override
  State<QDropDownList> createState() => _QDropDownListState();
}

class _QDropDownListState extends State<QDropDownList> {
  dynamic selectedItem;

  @override
  void initState() {
    super.initState();
    selectedItem = widget.selectedItem;
  }

  @override
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        widget.isTitleAbove
            ? Padding(
                padding: const EdgeInsets.only(top: 8.0),
                child: RichText(
                  text: TextSpan(
                      text: widget.title,
                      style: Theme.of(context).inputDecorationTheme.labelStyle,
                      children: [
                        TextSpan(
                            text: widget.isMandatory ? ' *' : '',
                            style: Theme.of(context)
                                .inputDecorationTheme
                                .labelStyle
                                ?.copyWith(color: Colors.red))
                      ]),
                ),
              )
            : const SizedBox(),
        Padding(
            padding: const EdgeInsets.only(top: 8.0),
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              child: DropdownButtonFormField<dynamic>(
                value: selectedItem,
                icon: widget.arrowIcon,
                isDense: true,
                isExpanded: false,
                style: Theme.of(context).dropdownMenuTheme.textStyle,
                hint: Text(widget.dropDownHint,
                    style: Theme.of(context).dropdownMenuTheme.textStyle),
                // ignore: prefer_is_empty
                items:widget.dropdownList.length>0? widget.dropdownList.map((data) {
                  return DropdownMenuItem<dynamic>(
                    value: data,
                    child: Text(
                      data.toString(),
                      style: Theme.of(context).dropdownMenuTheme.textStyle,
                    ),
                  );
                }).toList():[],
                onChanged: (dynamic value) {
                  setState(() {
                    selectedItem = value;
                    widget.onChanged(value);
                    debugPrint('Drop down change ---> $selectedItem');
                  });
                },
                validator: (value) {
                  if (widget.isMandatory) {
                    return value == null ? 'Field required' : null;
                  } else {
                    return null;
                  }
                },
              ),
            )),
      ],
    );
  }
}

enter image description here

>Solution :

The problem lies in QDropDownList. The widget gets a selectedValue but its state has a separate selectedValue. This one is only set in the initState. Which means that later on when you set the selectedValue to null it will not be changed in its state because that only happens when it’s first initialized in initState My suggestion is to completely remove the one from the state and rely on the widget’s selectedState. So in all:

Remove these lines:

  dynamic selectedItem;

  @override
  void initState() {
    super.initState();
    selectedItem = widget.selectedItem;
  }

Change:

value: selectedItem,

to

value: widget.selectedItem,

And finally change

            onChanged: (dynamic value) {
              setState(() {
                selectedItem = value;
                widget.onChanged(value);
                debugPrint('Drop down change ---> $selectedItem');
              });
            },

to

            onChanged: (dynamic value) {
              setState(() {
                widget.onChanged(value);
                debugPrint('Drop down change ---> $selectedItem');
              });
            },

Note that you don’t need to set a selected state here because the widgets onChanged will take care of that

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading