How can I get data from Map and put it in dropdown menu? I have an api working on websocket which returns me a Map of objects like {"1":"cat", "2":"dog","3":"bird"}
, so I wanted to create a dropdown where users can choose the animal. As I know, the Map has key/value pair, so I need to use value in my case for drop-down menu. So my code now looks like that:
body: Futurebuilder<Map>(
future: apiservice.getAnimal(),
builder:(context, snapshot){
return: DropdownButton(
value: snaphot.data.first,
onChanged: (String newValue) {
setState(() {
snapshot.data.first = newValue;
});
},
items: snapshot.data.values.map((key, value) {
return DropdownMenuItem(
value: i,
child: Text(value));
}).toList(),
);})
But data doesn't display or it gives the error that string can't be the Map<dynamic, dynamic>. How can I solve it?
CodePudding user response:
because the init value and the onChanged return value is a Map, You should change into into either a key or a value
Also, snapshot data is immutable and won't persisted, so you should create a list outside of the rebuild
//somewhere in your code, outside the rebuild method
String selectedAnimal = "";
var map = [];
body: Futurebuilder<Map<String,String>>(
future: apiservice.getAnimal(),
builder:(context, snapshot){
map = snapshot.data;
return: DropdownButton(
value: selectedAnimal ?? map.keys.first,
onChanged: (String newValue) {
setState(() {
selectedAnimal = map[newValue];
});
},
items: map.map((key, value) {
return DropdownMenuItem(
value: key,
child: Text(value));
}).toList(),
);})
CodePudding user response:
It better to create future outside the build method, like on state class or on initState.
late final _apiService = apiservice.getAnimal();
String? selected;
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<Map<String, String>>(
builder: (context, snapshot) {
if (snapshot.hasData) {
final Map<String, String> data = snapshot.data!;
return DropdownButton<String?>(
items: data.keys
.toList()
.map(
(e) => DropdownMenuItem<String>(
child: Text(
data[e] ?? "",
),
value: data[e],
),
)
.toList(),
onChanged: (v) {
setState(() {
selected = v;
});
},
);
}
return CircularProgressIndicator();
},
),
);
}