Flutter 从 Json 转换嵌套对象返回 null
Posted
技术标签:
【中文标题】Flutter 从 Json 转换嵌套对象返回 null【英文标题】:Flutter converting Nested Object from Json returns 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 的练习来获取它 【参考方案1】:先阅读这篇文章。
您需要稍微修改一下这段代码才能为您工作,但想法是这样; 还要阅读代码中的注释。
如果json字符串自带[]
,json.decode会将其解码为List<Map>
。
如果它带有,这个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 谢谢你,没问题,我刚刚给你赏金,因为你处理了这个问题,谢谢以上是关于Flutter 从 Json 转换嵌套对象返回 null的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 在 ListView 返回类型 String 中显示嵌套 json 不是类型转换中类型“Map<String, dynamic>”的子类型
如何将复杂(嵌套)对象解析为 JSON 并在 Flutter 中使用 HTTP 将其发送到服务器?