i'm trying to get a list of elements from the cloud firestore and then pass them into DropdownButtonFormField items, the thing is that i'm able to print them in the console but they are not being shown in the DropdownButtonFormField.
Here is my code:
List<String> companies = [];
Future getCompanies() async {
await FirebaseFirestore.instance
.collection('users_web')
.get()
.then((value) {
value.docs.forEach((element) {
companies.add(element['nom']);
print(companies.toList());
});
});
}
@override
void initState() {
getCompanies();
super.initState();
}
The DropdownButtonFormField:
DropdownButtonFormField<String>(
decoration: InputDecoration(
border: InputBorder.none,
),
hint: Text('Sélectionner votre société'),
items: companies.map(buildMenuItem).toList(),
onChanged: (value) {
setState(() {
company = value!;
});
},
validator: (value) {
if (!isChecked) {
if (value == null) {
return 'Ce champ ne doit pas être vide';
}
}
},
value: company,
isExpanded: true,
iconSize: 26,
icon: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(
Icons.arrow_drop_down,
color: Colors.black,
),
),
),
I'd be grateful for any help, thanks in advance!
CodePudding user response:
The problem is that your data is fetched async. Your screen is build before the getCompanies
is finished. The best way would be to use a FutureBuilder
but calling a setState
after the data is loaded might be good enough for your case
Future getCompanies() async {
await FirebaseFirestore.instance
.collection('users_web')
.get()
.then((value) {
value.docs.forEach((element) {
companies.add(element['nom']);
print(companies.toList());
});
});
setState((){});
}
CodePudding user response:
// example of your data
List<String> companies = ['item 1','item 2','item 3'];
DropdownButtonFormField<String>(
decoration: InputDecoration(
border: InputBorder.none,
),
hint: Text('Sélectionner votre société'),
items: List.generate(companies.length, (index) {
return DropdownMenuItem(
child: Text(companies[index]),
value: companies[index],
);
}),
onChanged: (value) {},
validator: (value) {},
value: companies.length > 0 ? companies[0] : null,
isExpanded: true,
iconSize: 26,
icon: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(
Icons.arrow_drop_down,
color: Colors.black,
),
),
)
CodePudding user response:
companies is a List of Strings so you can put it as is in the items: field
BEFORE:
items: companies.map(buildMenuItem).toList(),
AFTER:
items: companies,