Home > Net >  Cannot render data in DropdownMenu from API Call in Flutter
Cannot render data in DropdownMenu from API Call in Flutter

Time:04-25

I'm trying to create a Dropdown Menu in my project where the data that needs to be shown in the list is derived from an API call the response for which is given below. However, I get the below error saying and I have no idea how to resolve this:

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

The JSON response that I intend to work with(I need to show the name in my dropdown list):

[
    {
        "id": 3,
        "name": "Fruits and Vegetables",
        "active": true
    },
    {
        "id": 4,
        "name": "Grocery and Staples",
        "active": true
    }
]

This is my code:

class AddProductsPageState extends State<AddProductsPage> {
  final GlobalKey<FormState> _key = GlobalKey<FormState>();
  String dropDownValue = '';
  List<dynamic> list = [];
  bool isLoading = true;

  @override
  void initState() {
    // TODO: implement initState
    Provider.of<CategoryProvider>(context, listen: false)
        .getCategories()
        .then((_) {
      setState(() {
        isLoading = false;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height;
    final width = MediaQuery.of(context).size.width;
    final provider = Provider.of<CategoryProvider>(context).categoryList;
    list = provider;

    print('LIST $list');

    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).scaffoldBackgroundColor,
        automaticallyImplyLeading: false,
        elevation: 0,
        centerTitle: true,
        leading: InkWell(
          onTap: () => Navigator.of(context).pop(),
          child: Padding(
            padding: EdgeInsets.only(
                left: width * 0.005,
                top: height * 0.003,
                right: width * 0.005,
                bottom: height * 0.003),
            child: Container(
              width: width * 0.1,
              height: height * 0.1,
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                  boxShadow: const [
                    BoxShadow(
                      color: Colors.grey,
                      blurRadius: 10,
                      offset: Offset(1, 2),
                    )
                  ]),
              child: const Icon(Icons.arrow_back_ios, color: Colors.green),
            ),
          ),
        ),
        title: const Text(
          'Add Products',
          style: TextStyle(
              color: Color.fromARGB(255, 36, 71, 100),
              fontWeight: FontWeight.bold,
              fontSize: 25),
        ),
      ),
      body: isLoading
          ? const Center(
              child: CircularProgressIndicator(
                color: Colors.green,
              ),
            )
          : Container(
              width: double.infinity,
              height: double.infinity,
              // color: Colors.red,
              padding: EdgeInsets.all(width * 0.04),
              child: Form(
                key: _key,
                child: ListView(
                  children: [
                    const Text(
                      'Select Category',
                      style: TextStyle(
                          color: Color.fromARGB(255, 36, 71, 100),
                          fontWeight: FontWeight.bold,
                          fontSize: 15),
                    ),
                    DropdownButton(        //This is where the error is pointed at
                        value: dropDownValue ?? null,
                        items: provider.map((e) {
                          return DropdownMenuItem(
                            value: e,
                            child: Text(e['name']),
                          );
                        }).toList(),
                        onChanged: (value) {
                          setState(() {
                            dropDownValue = value.toString();
                          });
                        })
                  ],
                ),
              ),
            ),
    );
  }
}

Any help would be appreciated

CodePudding user response:

Try below code I think your problem has been solved.

Your JSON String, id and List declartion

 String jsonString =
      '[ { "id": 3, "name": "Fruits and Vegetables", "active": true },{ "id": 4, "name": "Grocery and Staples", "active": true }]';
  String id;
  List data = [];

API function:

 Future fetchJSONData() async {
    var jsonData = json.decode(jsonString);
    setState(() {
      data = jsonData;
    });
    return jsonData;
  }

call your API fetchJSONData() inside initState()

  @override
  void initState() {
    super.initState();
    fetchJSONData();
  }

Your Widget:

Container(
        width: 200,
        child: InputDecorator(
          decoration: InputDecoration(
            border: OutlineInputBorder(),
          ),
          child: DropdownButtonHideUnderline(
            child: DropdownButton(
              isDense: true,
              isExpanded: true,
              value: id,
              hint: Text("Select Data", style: TextStyle(color: Colors.black)),
              items: data.map((list) {
                return DropdownMenuItem(
                  child: Text(list['name']),
                  value: list['id'].toString(),
                );
              }).toList(),
              onChanged: (value) {
                setState(() {
                  id = value as String;
                });
              },
            ),
          ),
        ),
      ),

Your DropdownButton Widget-> image

Your DropdownButton Data-> image

  • Related