DropdownButton value is not updating after selecting values from DropdownItems. How to update default value with selectedValue?

Viewed 4895
DropdownButton Value does not update even after selecting different items.

If default value is null then error message is shown and if I pass any default value (not null) then it never changes to other selected values.

currentCategory is set as default value for DropdownButton.

StreamBuilder<QuerySnapshot>(
                    stream: Firestore.instance
                        .collection('categories')
                        .snapshots(),
                    builder: (BuildContext context,
                        AsyncSnapshot<QuerySnapshot> snapshot) {
                      currentCategory = snapshot.data.documents[0];
                      return DropdownButtonHideUnderline(
                        child:
                            new DropdownButtonFormField<DocumentSnapshot>(
                          value: currentCategory,
                          onChanged: (DocumentSnapshot newValue) {
                            setState(() {
                              currentCategory = newValue;
                            });
                            print(currentCategory.data['name']);
                          },
                          onSaved: (DocumentSnapshot newValue) {
                            setState(() {
                              currentCategory = newValue;
                            });
                          },
                          items: snapshot.data.documents
                              .map((DocumentSnapshot document) {
                            return new DropdownMenuItem<DocumentSnapshot>(
                              value: document,
                              child: Text(
                                document.data['name'],
                              ),
                            );
                          }).toList(),
                        ),
                      );
                    }),

help me to resolve this issue. Thanks in advance.

2 Answers

Triggering setState will schedule a new build (the build method is always called after receiving a call to setState).

So I suggest you to move your query outside your widget and initialize the stream in a initState statement so that it is not computed every time the state change (unless you really need it).

Also move your currentCategory outside the widget build method.

Something like this should work :

class YourClass extends StatefulWidget {
  ...
}

class _YourClassState extends State<YourClass> {

  Stream<QuerySnapshot> _categories;
  DocumentSnapshot _currentCategory;

  initState() {
    _categories = Firestore.instance.collection('categories').snapshots();
    return super.initState();
  }

  Widget build(BuildContext context) {
    return Container(
      child: StreamBuilder<QuerySnapshot>(
        stream: _categories,
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          return DropdownButtonHideUnderline(
            child: new DropdownButtonFormField<DocumentSnapshot>(
              value: _currentCategory,
              onChanged: (DocumentSnapshot newValue) {
                setState(() {
                  _currentCategory = newValue;
                });
              }
            )
          )
        }
      )
    );
  }

}

Also note that setState only work for stateful widgets.

That's because everytime you do a setState even though the currentCategory changed, it will rebuild your tree and go through currentCategory = snapshot.data.documents[0]; back again giving you the idea that is not being set.

Replace it by if(currentCategory == null) currentCategory = snapshot.data.documents[0]; so it will be set only if this condition is met.

Related