Aditya Dixit
Aditya Dixit

Reputation: 255

"There should be exactly one item with [DropdownButton]'s value: Item1" error when using dropdownbutton in flutter

I am trying to use the dropdown menu in my flutter app but getting an error.

Here is the code:

List<String> items = ["Item1", "Item2", "Item3", "Item4"];
String selectedItem = "Item1";
DropdownButton<String>(
  items: items.map(
    (txt) {
      return DropdownMenuItem<String>(
        child: Text(
          "$txt"
        ),
      );
    }
  ).toList(),
  value: selectedItem,
)

In some questions, I saw that we have to initially set a variable to the value present inside our list. I have exactly done that but still getting an error.

Error Message:

There should be exactly one item with [DropdownButton]'s value: Item1. 
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 850 pos 15: 'items == null || items.isEmpty || value == null ||
              items.where((DropdownMenuItem<T> item) {
                return item.value == value;
              }).length == 1'

What is the error here?

Kindly comment if more information is needed.

Upvotes: 4

Views: 4964

Answers (4)

user3317901
user3317901

Reputation: 3

   Visibility(
                  visible: isVisibleDitrict,
                  child: Column(
                    children: [
                      Center(
                        child: FutureBuilder<List<DataDsiricst>>(
                            future: _getDistrictData(stateCodeDPM),
                            builder: (context, snapshot) {
                              if (snapshot.hasError) {
                                return Text('Error: ${snapshot.error}');
                              }
                              if (snapshot.data == null) {
                                return const CircularProgressIndicator();
                              }
                              developer.log(
                                  '@@snapshot' + snapshot.data.toString());

                              List list = snapshot.data
                                  .map<DataDsiricst>((district) {
                                return district;
                              }).toList();
                              if (_selectedUserDistrict == null ||
                                  list.contains(_selectedUserDistrict) ==
                                      false) {
                                _selectedUserDistrict = list.first;
                              }
                              return Padding(
                                padding: const EdgeInsets.fromLTRB(
                                    20, 10, 20.0, 0),
                                child: Column(
                                  mainAxisAlignment:
                                      MainAxisAlignment.start,
                                  children: <Widget>[
                                    const Text(
                                      'Select District:',
                                    ),
                                    DropdownButtonFormField<DataDsiricst>(
                                      onChanged: (districtUser) =>
                                          setState(() {
                                        _selectedUserDistrict =
                                            districtUser;
                                        distCodeDPM = int.parse(
                                            (districtUser.districtCode
                                                .toString()));
                                        print('@@@Districtuser' +
                                            districtUser.districtName
                                                .toString());
                                        setState(() {});
                                      }),
                                      value: _selectedUserDistrict,
                                      items: snapshot.data.map<
                                              DropdownMenuItem<
                                                  DataDsiricst>>(
                                          (DataDsiricst district) {
                                        return DropdownMenuItem<
                                            DataDsiricst>(
                                          value: district,
                                          child:
                                              Text(district.districtName),
                                        );
                                      }).toList(),
                                      /*      items: [
                                        ...snapshot.data
                                            .map(
                                              (userDistricts) =>
                                                  DropdownMenuItem(
                                                value: userDistricts,
                                                child: Text(userDistricts
                                                    .districtName),
                                              ),
                                            )
                                            .toList()
                                      ],*/
                                    ),
                                  ],
                                ),
                              );
                            }),
                      ),
                    ],
                  ),
                ),

Model class : enter image description here

Upvotes: 0

Wilson Toribio
Wilson Toribio

Reputation: 1126

Here an example, the explanation in the code:

class _MyHomePageState extends State<MyHomePage> {

  List<String> items = ["Item1", "Item2", "Item3", "Item4"];
  String selectedItem = "Item1";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Column(
        children: [

          Flex(direction: Axis.vertical, children:[
            DropdownButton<String>(
              value: selectedItem,
              onChanged: (itemValue) {  // update the selectedItem value
                setState(() {
                  selectedItem = itemValue!;
                });
              },
              items: items
                  .map<DropdownMenuItem<String>>((String value) => DropdownMenuItem<String>(
                  value: value, // add this property an pass the value to it
                  child: Text(value,)
              )).toList(),
            ),
          ])

        ],
      ),

    );
  }
}

Upvotes: 5

muhsin
muhsin

Reputation: 35

List<String> items = ["Item1", "Item2", "Item3", "Item4"];
String selectedItem = "";
DropdownButton<String>(
  items: items.map(
    (txt) {
      return DropdownMenuItem<String>(
        child: Text("$txt"),
      );
    }
  ).toList(),
  value: selectedItem==""null?"":selectedItem,
)

Upvotes: 1

Arinzehills
Arinzehills

Reputation: 2329

If you are loading the list from an api that returns list, look at what i did to debug the error.

  1. Created a reusable widget that handle future response

     Widget rangeLists(selectedValue) {
     return FutureBuilder(
         future: YourFuture,//this should return Future<List>
         builder: (context, snapshot) {
           if (!snapshot.hasData) {
             return Text('Loading...');
           } else {
             List<DropdownMenuItem<String>> categoriesItems = [
               DropdownMenuItem(
                 child: Text(selectedValue),
                 value: selectedValue,
               ),
             ];
             print('categoriesItems.last.value');
             print(categoriesItems.last.value);
             var snapshotAsMap = snapshot.data as List;
             for (int i = 0; i < snapshotAsMap.length; i++) {
               if (snapshotAsMap[i]['category'] != selectedValue) {
                 categoriesItems.add(
                   DropdownMenuItem(
                     child: Text(snapshotAsMap[i]['category']),
                     value: snapshotAsMap[i]['category'],
                   ),
                 );
               }
             }
             return Padding(
               padding: const EdgeInsets.only(left: 18.0, right: 18, top: 10),
               child: Container(
                 padding: EdgeInsets.only(left: 25, right: 25),
                 decoration: BoxDecoration(
                     border: Border.all(color: Colors.grey, width: 1),
                     borderRadius: BorderRadius.circular(25)),
                 child: DropdownButton<String>(
                   items: categoriesItems,
                   icon: const Icon(
                     Icons.expand_more,
                     color: Colors.grey,
                   ),
                   iconSize: 24,
                   elevation: 16,
                   isExpanded: true,
                   style: const TextStyle(color: Colors.grey),
                   underline: SizedBox(),
                   onChanged: (value) {
                     setState(() {
                       widget.selectedValue = value;
                     });
                   },
                   value: selectedValue,
                   hint: Text('My courses'),
                 ),
               ),
             );
           }
         })};
    

2.Usage you can called it like this

String selectedValue="Select Here"

rangeLists(selectedValue)//call this as a widget in ur ui

It will handle all list from the backend u don't need to worry about the error any more

Upvotes: 0

Related Questions