Search code examples
flutterfirebasedartgoogle-cloud-firestoredropdown

Dropdown is not changing value on onChanged


I am fetching my firestore data and showing it in a dropdown list but in that list when i click on any item then the value or we can say hint text of dropdown doesn't change.

StreamBuilder<QuerySnapshot>(stream: compDoc.snapshots(),builder: (context, snapshot) {String? selectedValue;if (snapshot.hasError) {return Center(child: Text("Some error occurred ${snapshot.error}"),);}List<DropdownMenuItem> compItems = [];if (!snapshot.hasData) {return const CircularProgressIndicator();} else {final selectComp = snapshot.data?.docs.toList();if (selectComp != null) {`

`    for (var comp in selectComp) {
      compItems.add(
        DropdownMenuItem(
          value: comp['name'],
          child: Text(
            comp['name'],
          ),
        ),
      );
    }
  }
  return Padding(
    padding: const EdgeInsets.all(10.0),
    child: Container(
      padding: const EdgeInsets.only(right: 15, left: 15),
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey, width: 1),
        borderRadius: BorderRadius.circular(15),
      ),
      child: DropdownButton(
        underline: const SizedBox(),
        isExpanded: true,
        hint: Text(
          "Select items",
          style: TextStyle(fontSize: 20),
        ),
        value: selectedValue,
        items: compItems,
        onChanged: (value) {
          setState(() {
            selectedValue = value;
            print(selectedValue);
          });
        },
      ),
    ),
  );
}

Kindly someone help me.. i am stuck with that thing


Solution

  • This happens because you put selectedValue inside the builder callback of the StreamBuilder. Move selectedValue to the State of the widget that wraps this StreamBuilder. For example:

    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      String? selectedValue;
    
      @override
      Widget build(BuildContext context) {
        // return the StreamBuilder widget here
        // (or the widget that has that StreamBuilder somewhere in the widget tree)
        return StreamBuilder(
          builder: (context, snapshot) {
            String? selectedValue; // REMOVE this line
            // ...
          },
          // ...
        );
      }
    }
    
    

    You can see an example usage of setState with dropdown in the documentation.