【问题标题】:No such metthod error even after null check Flutter即使在 null 检查 Flutter 之后也没有这样的方法错误
【发布时间】:2020-12-25 14:13:54
【问题描述】:

在检查可能不存在的值时,我在使用 edamam api 时遇到了一些问题。查询“一个披萨”之类的营养价值时,没有错误,数据返回成功,但大多数查询并非如此,例如“一碗汤”。

我有一个未来的构建器,一旦用户按下按钮后在文本字段中发送查询,它就会更新

if (snapshot.connectionState == ConnectionState.done &&
        snapshot.hasData &&
        !snapshot.hasError &&
        snapshot.data != null) {
      energy = snapshot.data['totalDaily']['ENERC_KCAL']['quantity'] == null
          ? 0.0
          : snapshot.data['totalDaily']['ENERC_KCAL']['quantity'];
      fat = snapshot.data['totalDaily']['FAT']['quantity'] == null
          ? 0.0
          : snapshot.data['totalDaily']['FAT']['quantity'];
      protein = snapshot.data['totalDaily']['PROCNT']['quantity'] == null
          ? 0.0
          : snapshot.data['totalDaily']['PROCNT']['quantity'];
      cholesterol = snapshot.data['totalDaily']['CHOLE']['quantity'] == null
          ? 0.0
          : snapshot.data['totalDaily']['CHOLE']['quantity'];

变量获取信息并根据 if 检查返回加载程序或信息。我认为添加空检查可以防止任何错误,但它们似乎没有做任何事情。这是我得到的错误

The following NoSuchMethodError was thrown building FutureBuilder<dynamic>(dirty, state: _FutureBuilderState<dynamic>#3bbe5):
    The method '[]' was called on null.
    Receiver: null
    Tried calling: []("quantity")

有没有更好的方法来做到这一点?我在这里做错了什么?

【问题讨论】:

  • 你能提供你的错误日志吗?
  • 您的问题是您正在执行x['quantity'],其中xnull。您当前的空检查测试诸如snapshot.data['totalDaily']['ENERC_KCAL']['quantity'] 之类的东西不为空,但为时已晚;他们忽略了检查snapshot.data['totalDaily']['ENERC_KCAL'] 等是否不为空。如果您启用了 null-safety 功能,您可以查看snapshot.data['totalDaily']?['ENERC_KCAL']?['quantity'] == null
  • 所以我试了一下,就像你说的 jamesdlin 一样,问题已经解决了,非常感谢,但它很罗嗦。如何启用空安全功能,使其像您写的那样简化?
  • @NanaKwame 请检查我的答案以获得不那么冗长的解决方案
  • 启用空安全性可能比您现在愿意做的工作更多。同时,您也可以使用package:basicssnapshot.data.get('totalDaily')?.get('ENERC_KCAL')?.get('quantity') == null

标签: flutter dart


【解决方案1】:

首先,为了避免大多数错误和数据处理问题,我建议使用一个对象来表示您的食物信息。你可以使用this tool,选择 Dart 作为你的语言,然后粘贴 JSON 数据。你现在有这些对象:


class Food {
  Food({
    this.totalDaily,
  });

  TotalDaily totalDaily;

  factory Food.fromJson(Map<String, dynamic> json) => Food(
    totalDaily: TotalDaily.fromJson(json["totalDaily"]),
  );

  // I omit the toJson() method since it's not used in this question
}

class TotalDaily {
  TotalDaily({
    this.enercKcal,
    this.fat,
    this.procnt,
    this.chole,
  });

  NutritionValue enercKcal;
  NutritionValue fat;
  NutritionValue procnt;
  NutritionValue chole;

  factory TotalDaily.fromJson(Map<String, dynamic> json) => TotalDaily(
    enercKcal: NutritionValue.fromJson(json["ENERC_KCAL"]),
    fat: NutritionValue.fromJson(json["FAT"]),
    procnt: NutritionValue.fromJson(json["PROCNT"]),
    chole: NutritionValue.fromJson(json["CHOLE"]),
  );
}

class NutritionValue {
  NutritionValue({
    this.quantity,
  });

  int quantity;

  factory NutritionValue.fromJson(Map<String, dynamic> json) => NutritionValue(
    quantity: json["quantity"],
  );
}

那么你需要做的就是:

Food food = Food.fromJson(snapshot.data)

尝试调用:

对于这个问题,似乎错误可能来自使用quantity 属性的所有能量、脂肪、蛋白质或胆固醇解析。在这种情况下,您可以像这样进行简单的检查:

// Example for FAT checking
fat = food.totalDaily.fat?.quantity ?? 0.0

【讨论】:

  • 我不知道有一种自动化的方法可以做到这一点,简洁。非常感谢。
猜你喜欢
  • 2021-06-15
  • 2019-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
相关资源
最近更新 更多