There should be exactly one item with [DropdownButton]'s value

1,008

Try to set other dropdown value to null when changing the dropdown value in onChanged method

Share:
1,008
Abdi Nur
Author by

Abdi Nur

Updated on December 27, 2022

Comments

  • Abdi Nur
    Abdi Nur over 1 year

    I am building an app for an e-commerce system which can post data to the server. There are multiple item categories which have different and customizable values. For example, laptop category can have processor, ram, storage size attributes. Some of this attribute are textboxes (eg. model) while others need to be dropdowns (eg. processor - core i7, i5, etc...). The number of attributes can not be fixed since it depends on the category (might be added or removed anytime)

    I was trying to build a form which will show this attributes as a textbox or dropdown depending on the attribute type (AttributeType column). I was able to show both the textboxes and dropdowns (with their elements successfully. The problem I have is accessing dropdown values to create a post request to the server.

    Here is the code

     FutureBuilder<FormListModel>(
                    future: _formList,
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        return ListView.builder(
                          primary: false,
                          scrollDirection: Axis.vertical,
                          shrinkWrap: true,
                          itemCount: snapshot.data.customattributes.length,
                          itemBuilder: (context, index) {
                            var item = snapshot.data.customattributes[index];
                            print(item.name);
                            
                            if (item.AttributeType == 'Text') {
                              return Container(
                                //padding: EdgeInsets.only(top: 8),
                                margin:
                                    EdgeInsets.only(top: 15, left: 15, right: 15),
                                child: Column(
                                  children: [
                                    Form(
                                      child: TextFormField(
                                        controller: model_controller,
                                        decoration: InputDecoration(
                                          contentPadding: EdgeInsets.symmetric(
                                              vertical: 10, horizontal: 10),
                                          labelText: item.name,
                                          border: OutlineInputBorder(
                                            borderSide: BorderSide(
                                                color: Colors.blueAccent),
                                          ),
                                        ),
                                        onChanged: (value) {
                                          //print(model_controller.text);
                                        },
                                      ),
                                    ),
                                  ],
                                ),
                              );
                            } else if (item.AttributeType == 'Selectlist') {
                              return Container(
                                //padding: EdgeInsets.only(top: 8),
                                margin:
                                    EdgeInsets.only(top: 20, left: 15, right: 15),
                                child: Column(
                                  children: [
                                    Form(
                                      child: InputDecorator(
                                        decoration: InputDecoration(
                                          contentPadding: EdgeInsets.symmetric(
                                              vertical: 12, horizontal: 12),
                                          labelText: item.name,
                                          labelStyle: TextStyle(
                                              fontSize: 20,
                                              color: Colors.blueAccent),
                                          border: const OutlineInputBorder(),
                                        ),
                                        child: DropdownButtonHideUnderline(
                                          child: DropdownButton(
                                            isDense: true,
                                            icon: Icon(Icons.keyboard_arrow_down),
                                            value: selectedAttribute,
                                            onChanged: (newValue) {
                                              setState(() {
                                                selectedAttribute = newValue;
                                              });
                                            },
                                            //decoration: InputDecoration(border: InputBorder.none),
                                            items: item.children
                                                .map<DropdownMenuItem>((items) {
                                              return DropdownMenuItem<String>(
                                                child: Row(
                                                  children: [
                                                    Padding(
                                                      padding:
                                                          EdgeInsets.only(top: 7),
                                                      child: Text(items.element),
                                                    ),
                                                  ],
                                                ),
                                                value: items.element,
                                              );
                                            }).toList(),
                                          ),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              );
                            } else {
                              return null;
                            }
                          },
                        );
                      } else {
                        return Container();
                      }
                    }),
    

    Here is the json file which we get from the server to create the form using ListView.builder

    {
        "category": {
            "CategoryName": "Laptops",
            "CategoryID": 34
        },
        "customattributes": [
            {
                "Name": "Model",
                "AttributeType": "Text",
                "AttributeID": 7
            },
            {
                "Name": "Processor",
                "AttributeType": "Selectlist",
                "AttributeID": 2,
                "Children": [
                    {
                        "Element": "Intel Core i3"
                    },
                    {
                        "Element": "Intel Core i5"
                    },
                    {
                        "Element": "Intel Core i7"
                    }
                ]
            },
            {
                "Name": "Storage Size",
                "AttributeType": "Selectlist",
                "AttributeID": 1,
                "Children": [                
                    {
                        "Element": "1TB"
                    },
                    {
                        "Element": "2TB"
                    },
                    {
                        "Element": "2.5TB"
                    }
                ]
            },
            {
                "Name": "RAM",
                "AttributeType": "Selectlist",
                "AttributeID": 3,
                "Children": [
                    {
                        "Element": "12GB"
                    },
                    {
                        "Element": "16GB"
                ]
            }
        ],
        
    }
    

    Here is the form

    enter image description here

    When I select any value from the dropdown, I get an error which says, There should be exactly one item with [DropdownButton]'s value

    enter image description here

    1. So how can I access the values of each dropdown so that I can make http post request to the server. Please bear in mind that the number of dropdowns (attributes) is vary for each category. 2nd question, not that important but is there a way where I can assign a name for each dropdown using the 'Name' column of the attributes in the json file.
  • user3659497
    user3659497 over 3 years
    Is this to avoid seeing the error or to access the values? Because, I am pretty sure it won't make any sense to set other dropdown values to null if the users has already selected a value from the dropdown.
  • Admin
    Admin over 3 years
    i am pretty sure making null will work because it worked for me in past
  • Abdi Nur
    Abdi Nur over 3 years
    I tried your code and it says The getter 'attributeid' was called on null. Receiver: null Tried calling: attributeid
  • Gourango Sutradhar
    Gourango Sutradhar over 3 years
    I have edited the answer. Please check it.