Flutter : I have error when work with tow dropdown button load one from another

笑着哭i 提交于 2021-01-29 16:27:18

问题


Hello i am work with flutter drop down menu . firs menu for location . and second for sublocation . it is work when click on first location but when change to second and click second location this error appear "'package:flutter/src/material/dropdown.dart': Failed assertion: line 620 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) => item.value == value).length == 1': is not true. "

my variable

  //location
  String _myLocation ; 
  List data = List(); 
  //sublocation
  String _mySublocation  ; 
  List data2 = List(); 

function for location

Future  getLocation() async {
   try{
      var res = await http
        .get(Uri.encodeFull("http://iraqdoctors.com/api/locations"), headers: {"Accept": "application/json"});
    setState(() {
    var resBody = json.decode(res.body);
      data = resBody;
    });
    return "Sucess";
   }catch(e){

   }
  }//get location

function for sublocation

Future  getSublocation() async {
    try{
      var res2 = await http
        .post(Uri.encodeFull("http://iraqdoctors.com/api/getlocationflutter"),
         headers: {"Accept": "application/json"},
         body: {
            "cityname":"$_myLocation",  
          } 
         );   
    setState(() {
      var resBody2 = json.decode(res2.body);
      data2 = resBody2;
    });
    return "Sucess";
    }catch(e){

    }
  }//get sublocation

Location dropdown

 Container(     
          padding: EdgeInsets.only(right:10), 
        decoration: ShapeDecoration(
          color: Colors.white,
        shape: RoundedRectangleBorder(           
         borderRadius: BorderRadius.all(Radius.circular(8.0)),
        ),
      ),
       child:DropdownButton( //location                  
            icon: Icon(Icons.arrow_drop_down),
            iconSize: 24,
            elevation: 16,
            style: TextStyle(color: Colors.black, fontSize: 18),            
            value: _myLocation,
            items: data.map((item) {
              return new DropdownMenuItem(
                child: Text(item['city'],style: TextStyle(color: Colors.black)),
                value: item['city'],
              );
            }).toList(),
            onChanged: ( newVal) {
              setState(() {
                _myLocation = newVal;  
                getSublocation();              
              });
            },     
            isExpanded: true,
             underline: SizedBox(),                       
            iconEnabledColor: Colors.white,
            hint: Text('اختر المدينة',style: TextStyle(color: Colors.black),),    
        ),),

Sublocation dropdown

 Container(        
        padding: EdgeInsets.only(right:10),       
        decoration: ShapeDecoration(
        color: Colors.white,
        shape: RoundedRectangleBorder(           
         borderRadius: BorderRadius.all(Radius.circular(8.0)),
        ),
      ),
       child:  DropdownButton(//sublocation           
            icon: Icon(Icons.arrow_drop_down),
            iconSize: 24,
            elevation: 16,
            style: TextStyle(color: Colors.black, fontSize: 18) ,           
            items: data2.map((item) {               
                return new DropdownMenuItem(
                child: Text(item['state'],style: TextStyle(color: Colors.black)),
                value: item['id'].toString(),
              );
            }).toList(),
            onChanged: (value) {
              setState(() {
                    _mySublocation = value  ;        
               });
            },
             value: _mySublocation ,
             isExpanded: true,
             hint: Text('اختر المنطقة',style: TextStyle(color: Colors.black),), 
             underline: SizedBox(),
             iconEnabledColor: Colors.white,
            ),),
                 ```

回答1:


itry your code but still same error when load sublocation menu




回答2:


You can copy paste run full code below
I use 2 seconds delay to simulate your http task
The error message means data2 is null
In your onChanged, you need to await await getSublocation()
and make sure convert json to data2 is correct

code snippet

onChanged: (newVal) async {
                  _myLocation = newVal;
                  await getSublocation();
                  setState(() {});
                },

working demo

full code

    import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String _myLocation = null;
  List data = List();
  //sublocation
  String _mySublocation = null;
  List data2 = List();

  Future getLocation() async {
    try {
      /* var res = await http.get(
          Uri.encodeFull("http://iraqdoctors.com/api/locations"),
          headers: {"Accept": "application/json"});
      setState(() {
        var resBody = json.decode(res.body);
        data = resBody;
      });*/
      await Future.delayed(const Duration(seconds: 1), () {});
      data.clear();
      data.add({"city": "A"});
      data.add({"city": "B"});
      setState(() {});
      return "Sucess";
    } catch (e) {}
  } //get location

  Future getSublocation() async {
    try {
      /*var res2 = await http.post(
          Uri.encodeFull("http://iraqdoctors.com/api/getlocationflutter"),
          headers: {
            "Accept": "application/json"
          },
          body: {
            "cityname": "$_myLocation",
          });
      setState(() {
        var resBody2 = json.decode(res2.body);
        data2 = resBody2;
      });*/
      await Future.delayed(const Duration(seconds: 2), () {});

      String jsonString = '''
      [ { "id": 1, "state": "الحارثية", "city": "بغداد", "created_at": "2019-12-17 07:20:16", "updated_at": "2019-12-17 07:20:16" } ] 
      ''';

      data2.clear();
      data2 = json.decode(jsonString);
      /*data2.clear();
      data2.add({"state": "A1", "id": "a1"});
      data2.add({"state": "B1", "id": "b1"});*/
      print(data2.toString());
      print(data2[0]['state'].toString());
      setState(() {});
      return "Sucess";
    } catch (e) {
      print(e.toString());
    }
  } //get sublocation

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      getLocation();
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              padding: EdgeInsets.only(right: 10),
              decoration: ShapeDecoration(
                color: Colors.white,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8.0)),
                ),
              ),
              child: DropdownButton(
                //location
                icon: Icon(Icons.arrow_drop_down),
                iconSize: 24,
                elevation: 16,
                style: TextStyle(color: Colors.black, fontSize: 18),
                value: _myLocation,
                items: data.map((item) {
                  return new DropdownMenuItem(
                    child: Text(' ${item['city']} ',
                        style: TextStyle(color: Colors.black)),
                    value: item['city'],
                  );
                }).toList(),
                onChanged: (newVal) async {
                  _myLocation = newVal;
                  await getSublocation();
                  setState(() {});
                },
                isExpanded: true,
                underline: SizedBox(),
                iconEnabledColor: Colors.white,
                hint: Text(
                  'اختر المدينة',
                  style: TextStyle(color: Colors.black),
                ),
              ),
            ),
            Container(
              padding: EdgeInsets.only(right: 10),
              decoration: ShapeDecoration(
                color: Colors.white,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8.0)),
                ),
              ),
              child: DropdownButton(
                //sublocation
                icon: Icon(Icons.arrow_drop_down),
                iconSize: 24,
                elevation: 16,
                style: TextStyle(color: Colors.black, fontSize: 18),
                items: data2.map((item) {
                  return new DropdownMenuItem(
                    child: Text(' ${item['state']}',
                        style: TextStyle(color: Colors.black)),
                    value: item['id'].toString(),
                  );
                }).toList(),
                onChanged: (value) {
                  setState(() {
                    _mySublocation = value;
                  });
                },
                value: _mySublocation,
                isExpanded: true,
                hint: Text(
                  'اختر المنطقة',
                  style: TextStyle(color: Colors.black),
                ),
                underline: SizedBox(),
                iconEnabledColor: Colors.white,
              ),
            ),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}


来源:https://stackoverflow.com/questions/59604124/flutter-i-have-error-when-work-with-tow-dropdown-button-load-one-from-another

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!