首页 > 解决方案 > Flutter Firebase - DropdownMenuItem:方法'map'在null上被调用

问题描述

在我的申请中,我想根据动物的种类(如果是狗或猫)展示疫苗。我遇到了一个错误:在 null 上调用了方法“map”。尝试调用: map DropdownMenuItem。为什么会这样?我已经在方法中放入了 async 和 await ,我不明白为什么它仍然为空。咆哮我的代码:

1)这是我在 init 中调用我的 DropdownContent 类以在小部件内的行中准备我的 DropdownMenuItem 的地方

class _VaccineDetailFormState extends State<VaccineDetailForm> {

final DataRepository repository = DataRepository();
String selectedVaccine = "Select";
List<String> vaccinesBySpecie;

  initState() {
    DropdownContent.getVaccines(widget.selectedPetID).then((value) => vaccinesBySpecie = value);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
    [...]
              new Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new DropdownButton<String>(
                      value:  widget.vaccine.name == null ? selectedVaccine: widget.vaccine.name,
                      underline: Container(
                        height: 2,
                        color: Colors.grey,
                      ),
                      onChanged: (String newValue) {
                        setState(() {
                          selectedVaccine = newValue;
                          widget.vaccine.name = newValue;
                        });
                      },
                      items: vaccinesBySpecie.map<DropdownMenuItem<String>>((String value) {
                        return DropdownMenuItem<String>(
                          value: value,
                          child: Text(value),
                        );
                      }).toList(),
                    )
                  ]),

                  [...]

2) 这是 DropdownContent 类,它在 getVaccines() 方法中搜索存储库以找出当前动物的物种,然后返回适当的疫苗列表。

class Dropdown content

static Future<List<String>> getVaccines(String petId) async {

    final DataRepository repository = DataRepository();
    String currentSpecie = await repository.getSpecie(petId);

    if (currentSpecie.contains('Dog')) {
      return listOfVaccinesForDogs();
    }
    if (currentSpecie.contains('Cat')) {
      return listOfVaccinesForCats();
    }
}

3)最后,搜索动物物种的存储库类

 class Repository

   Future<String> getSpecie(String petId) async {
    DocumentReference documentReference = petCollection.document(petId);
    await documentReference.get().then((snapshot) {
      return snapshot.data['specie'].toString();
    });
  }

标签: androidiosfirebaseflutterdart

解决方案


虽然您的 initState 方法可能是异步的,但您的构建方法却不是。因此,在调用 build 方法时,您的 vaccinesBySpecie 方法为空。解决此问题的最佳方法是初始化您的List<String> vaccinesBySpecielike so List<String> vaccinesBySpecie = [];。这样在调用 build 方法时它不为空。

作为旁注,如果可以的话,我建议使用 FutureBuilder 或 StreamBuilder,这样你可以处理没有值(即它为空)与有值时(即它不为空)


推荐阅读