【问题标题】:Flutter converting Nested Object from Json returns nullFlutter 从 Json 转换嵌套对象返回 null
【发布时间】:2021-02-04 11:20:42
【问题描述】:

我有一个像这样稍微大一点的嵌套对象:

"name": "String",       
    "exercise": [               
                   {                
                   "index": 1,                                  
                   }            
            ],              
    "pause": [              
        {"index":2},                        
    ]           

我将练习和暂停转换为 Json 字符串并将它们保存在 SQFLite 的列中。

问题

当我读取数据时,一切正常,包括列表(未嵌套),但是当我读取嵌套对象的值时,嵌套对象的两个列表都是空的。

item.exercise[0].index.toString()

Valid Value range is empty: 0

当我只读取item.exercise.toString() 时,它会返回[]。没有!= null ? [...] : List<Exercise>() 也会抛出错误

我从数据库中获得的数据(缩短)

列表:

[{name: number 1, id: 56, exercise: [{"index":1,"weightGoal":[15,16,17]}, {"index":3,"weightGoal":[15,16,17]}], pause: [{"index":2}]},{"index":4}]}]

我用它做什么

这里我尝试遍历列表并将其转换为 PlanModel 的列表:

List<PlanModel> list =
        res.isNotEmpty ? res.map((c) => PlanModel.fromJson(c)).toList() : [];
    return list;

完整模型

PlanModel planModelFromJson(String str) => PlanModel.fromJson(json.decode(str));

String planModelToJson(PlanModel data) => json.encode(data.toJson());

class PlanModel {
  PlanModel({
    this.name,
    this.id,
    this.workoutDays,
    this.pastId,
    this.timesDone,
    this.exercise,
    this.pause,
  });

  String name;
  int id;
  List<String> workoutDays;
  int pastId;
  int timesDone;
  List<Exercise> exercise;
  List<Pause> pause;

  factory PlanModel.fromJson(Map<String, dynamic> json) => PlanModel(
    name: json["name"],
    id: json["id"],
    workoutDays: List<String>.from(jsonDecode(json["workoutDays"])),
    pastId: json["pastId"],
    timesDone: json["timesDone"],
    exercise: json["Exercise"] != null ? new List<Exercise>.from(json["Exercise"].map((x) => Exercise.fromJson(x))): List<Exercise>(),
    pause: json["Pause"] != null ? new List<Pause>.from(json["Pause"].map((x) => Pause.fromJson(x))): List<Pause>(),
  );

  Map<String, dynamic> toJson() => {
    "name": name,
    "id": id,
    "workoutDays": List<dynamic>.from(workoutDays.map((x) => x)),
    "pastId": pastId,
    "timesDone": timesDone,
    "Exercise": List<dynamic>.from(exercise.map((x) => x.toJson())),
    "Pause": List<dynamic>.from(pause.map((x) => x.toJson())),
  };



}

class Exercise {
  Exercise({
    this.index,
    this.name,
    this.goal,
    this.repGoal,
    this.weightGoal,
    this.timeGoal,
    this.setGoal,
  });

  int index;
  String name;
  int goal;
  int repGoal;
  List<int> weightGoal;
  int timeGoal;
  List<String> setGoal;

  Exercise.fromJson(dynamic json) {
    // anything that is wrapped around with this [] in json is converted as list
    // anything that is wrapped around with this {} is map
    index = json["index"];
    name = json["name"];
    goal = json["goal"];
    repGoal = json["repGoal"];
    weightGoal = json["weightGoal"] != null ? json["weightGoal"].cast<int>() : [];
    timeGoal = json["timeGoal"];
    setGoal = json["setGoal"] != null ? json["setGoal"].cast<String>() : [];
  }

  Map<String, dynamic> toJson() => {
    "index": index,
    "name": name,
    "goal": goal,
    "repGoal": repGoal,
    "weightGoal": List<dynamic>.from(weightGoal.map((x) => x)),
    "timeGoal": timeGoal,
    "setGoal": List<dynamic>.from(setGoal.map((x) => x)),
  };
}

class Pause {
  Pause({
    this.index,
    this.timeInMilSec,
  });

  int index;
  int timeInMilSec;

  factory Pause.fromJson(Map<String, dynamic> json) => Pause(
    index: json["index"],
    timeInMilSec: json["timeInMilSec"],
  );

  Map<String, dynamic> toJson() => {
    "index": index,
    "timeInMilSec": timeInMilSec,
  };
}

【问题讨论】:

  • 我不确定,但我认为 key 区分大小写。您正在使用:json["Exercise"] 和 json["Pause"]
  • @ClaudioCastro 感谢您的评论,但这很好,我也将它们都初始化为大写,因为没有变量,而是类。
  • @M123 您能否将您获得的所有数据、完整版的 PlanModel 和完整版的练习提供给我们,以便我对其进行测试并从中取得成果?
  • @manofknowledge 给你
  • exercise 在数据库中是小写字母,但您尝试使用带有大写 E 的练习来获取它

标签: json flutter object dart constructor


【解决方案1】:

先阅读这篇文章。

您需要稍微修改一下这段代码才能为您工作,但想法是这样; 还要阅读代码中的注释。

如果json字符串自带[],json.decode会将其解码为List&lt;Map&gt;

如果它带有{},这个json.decode会将它解码为Map

注意:在 json.decode 上使用泛型时要小心,我建议不要这样做。

jsonString 内的数据与 fromJson 函数内的值并不真正对应。您提供的 json 字符串不是很好。所以我想你会明白如何根据自己的需要来操作它。

也是主构造函数Exercise,可用于初始数据。

import 'dart:convert';
class Exercise{
  Exercise({this.index, 
            this.name, 
            this.repGoal, 
            this.weightGoal, 
            this.setGoal});
  
  String index;
  String name;
  String repGoal;
  String weightGoal;
  String setGoal;


Exercise.fromJson(dynamic json) : 
    // anything that is wrapped around with this [] in json is converted as list
    // anything that is wrapped around with this {} is map
    index = json["exercise"][0]["index"].toString(),
    name = json["name"].toString(),
    repGoal = json["repGoal"].toString(),
    weightGoal = json["weightGoal"].toString(),
    setGoal = json["setGoal"].toString();
  
  
}

void main(){
  String jsonString = '{name: number 1, id: 56, exercise: [{"index":1,"weightGoal":[15,16,17], pause: [{"index":2}]}';
  Map json = json.decode(jsonString);
  Exercise.fromJson(json);
  
}

【讨论】:

  • 感谢您的回答,不胜感激。我尝试了更多并编辑了我的问题,但是我得到的练习列表是空的,这意味着,如果我尝试从练习 [0] 中获取一个值,我会收到一个错误
【解决方案2】:

我发现了:)

我已经将我的 fromJson 重组为这个,尤其是 jsonDecode 很重要,因为json["exercise "] 只是一个字符串。

PlanModel.fromJson(dynamic json) {
    name = json["name"];
    if (json["exercise"] != null) {
      exercise = [];
      jsonDecode(json["exercise"]).forEach((v) {
        exercise.add(Exercise.fromJson(v));
      });
    }}

现在我可以访问它了

PlanModel item = snapshot.data[index];

item.exercise[0].timeGoal.toString()
    

【讨论】:

  • 我真的为你感到高兴!抱歉我没能早点回答。
  • @manofknowledge 谢谢你,没问题,我刚刚给你赏金,因为你处理了这个问题,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多