如何用 Flutter 解析动态 JSON?
How to parse dynamic JSON with Flutter?
我不明白如何解析我从 firebase 获得的 JSON 文件。
这是JSON文件的格式
{
"water" : {
"-MnRJkFC3--ZOTmpF1xN" : {
"milliliters" : 0.14,
"time" : "16:26:25"
},
"-MnRJkZRwZYEInHfSKIY" : {
"milliliters" : 48.83,
"time" : "16:26:25"
},
"-MnRJksES18hY765rxxq" : {
"milliliters" : 41.44,
"time" : "16:26:25"
},
"-MnRJlDn6o4RmiGRJS-E" : {
"milliliters" : 11.37,
"time" : "16:26:25"
}
}
}
这就是我阅读 JSON 文件的方式
Future loadSalesData() async {
final String jsonString = await getJsonFromFirebase();
final dynamic jsonResponse = json.decode(jsonString);
for (Map<String, dynamic> i in jsonResponse)
chartData.add(SalesData.fromJson(i));
}
getJsonFromFirebase() 看起来像这样:
Future<String> getJsonFromFirebase() async {
String url =
"https://emailpassword. . .seio.com/water.json";
http.Response response = await http.get(Uri.parse(url));
return response.body;
}
当您点击 link 时,它会将您带到 JSON 文件,如下所示
{
"-Mnbk2ye2P8bfpaQvNaU": {
"milliliters": 0.0,
"time": "18:07:00"
},
"-Mnbk6wd-wJze8P0JknK": {
"milliliters": 0.12,
"time": "18:07:00"
},
"-Mnbk7Ek629vgBu-MiLg": {
"milliliters": 44.91,
"time": "18:07:00"
},
"-Mnbk7bPuzqwsz9d5nm6": {
"milliliters": 5.43,
"time": "18:07:00"
},
"-Mnbk7v7MADi7YzEbeFI": {
"milliliters": 24.54,
"time": "18:07:00"
},
"-Mnbk8DGfqswckdsA1qP": {
"milliliters": 47.58,
"time": "18:07:00"
},
"-Mnbk8Xw2kJPxLrqCl6h": {
"milliliters": 13.98,
"time": "18:07:00"
}
}
我收到错误
_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable'
似乎flutter
不明白jsonResponse
是一个iterable
因为你把它定义为dynamic
.
调整定义告诉flutter它是一个地图:
final Map<String, dynamic> jsonResponse = json.decode(jsonString);
根据您收到的 JSON 的形状,json.decode
will return a Map<String, dynamic>
(more specifically an instance of the _InternalLinkedHashMap<String, dynamic>
specialisation). This type doesn't implement Iterable
,因此您不能直接使用 for-in
构造对其进行迭代,这正是您遇到的错误在 运行 时间得到。
根据构建 SalesData
实例所需的内容,您有两个选择:
- 迭代
entries
属性,如果您需要每个项目的 key
("-Mnbk2ye2P8bfpaQvNaU"
、"-Mnbk6wd-wJze8P0JknK"
等),否则
- 迭代
values
属性,如果你不这样做
条目
迭代次数:
for (MapEntry<String, dynamic> i in jsonResponse.entries) {
chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson
:
SalesData.fromJson(MapEntry<String, dynamic> data) {
id = data.key;
milliliters = data.value['milliliters'];
time = data.value['time'];
}
值
迭代次数:
for (Map<String, dynamic> i in jsonResponse.values) {
chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson
:
SalesData.fromJson(Map<String, dynamic> data) {
milliliters = data['milliliters'];
time = data['time'];
}
类型推断
此外,无论您决定如何迭代 Map
实例,您都可以利用 Dart 的 type inference 稍微清理一下代码,所以(假设您正在迭代条目) loadSalesData
可以变成:
Future loadSalesData() async {
final jsonString = await getJsonFromFirebase();
final jsonResponse = json.decode(jsonString);
for (final i in jsonResponse.entries) {
chartData.add(SalesData.fromJson(i));
}
}
和getJsonFromFirebase
可以变成:
Future<String> getJsonFromFirebase() async {
final url = "http://localhost:8080/data.json";
final response = await http.get(Uri.parse(url));
return response.body;
}
我不明白如何解析我从 firebase 获得的 JSON 文件。
这是JSON文件的格式
{
"water" : {
"-MnRJkFC3--ZOTmpF1xN" : {
"milliliters" : 0.14,
"time" : "16:26:25"
},
"-MnRJkZRwZYEInHfSKIY" : {
"milliliters" : 48.83,
"time" : "16:26:25"
},
"-MnRJksES18hY765rxxq" : {
"milliliters" : 41.44,
"time" : "16:26:25"
},
"-MnRJlDn6o4RmiGRJS-E" : {
"milliliters" : 11.37,
"time" : "16:26:25"
}
}
}
这就是我阅读 JSON 文件的方式
Future loadSalesData() async {
final String jsonString = await getJsonFromFirebase();
final dynamic jsonResponse = json.decode(jsonString);
for (Map<String, dynamic> i in jsonResponse)
chartData.add(SalesData.fromJson(i));
}
getJsonFromFirebase() 看起来像这样:
Future<String> getJsonFromFirebase() async {
String url =
"https://emailpassword. . .seio.com/water.json";
http.Response response = await http.get(Uri.parse(url));
return response.body;
}
当您点击 link 时,它会将您带到 JSON 文件,如下所示
{
"-Mnbk2ye2P8bfpaQvNaU": {
"milliliters": 0.0,
"time": "18:07:00"
},
"-Mnbk6wd-wJze8P0JknK": {
"milliliters": 0.12,
"time": "18:07:00"
},
"-Mnbk7Ek629vgBu-MiLg": {
"milliliters": 44.91,
"time": "18:07:00"
},
"-Mnbk7bPuzqwsz9d5nm6": {
"milliliters": 5.43,
"time": "18:07:00"
},
"-Mnbk7v7MADi7YzEbeFI": {
"milliliters": 24.54,
"time": "18:07:00"
},
"-Mnbk8DGfqswckdsA1qP": {
"milliliters": 47.58,
"time": "18:07:00"
},
"-Mnbk8Xw2kJPxLrqCl6h": {
"milliliters": 13.98,
"time": "18:07:00"
}
}
我收到错误
_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable'
似乎flutter
不明白jsonResponse
是一个iterable
因为你把它定义为dynamic
.
调整定义告诉flutter它是一个地图:
final Map<String, dynamic> jsonResponse = json.decode(jsonString);
根据您收到的 JSON 的形状,json.decode
will return a Map<String, dynamic>
(more specifically an instance of the _InternalLinkedHashMap<String, dynamic>
specialisation). This type doesn't implement Iterable
,因此您不能直接使用 for-in
构造对其进行迭代,这正是您遇到的错误在 运行 时间得到。
根据构建 SalesData
实例所需的内容,您有两个选择:
- 迭代
entries
属性,如果您需要每个项目的key
("-Mnbk2ye2P8bfpaQvNaU"
、"-Mnbk6wd-wJze8P0JknK"
等),否则 - 迭代
values
属性,如果你不这样做
条目
迭代次数:
for (MapEntry<String, dynamic> i in jsonResponse.entries) {
chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson
:
SalesData.fromJson(MapEntry<String, dynamic> data) {
id = data.key;
milliliters = data.value['milliliters'];
time = data.value['time'];
}
值
迭代次数:
for (Map<String, dynamic> i in jsonResponse.values) {
chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson
:
SalesData.fromJson(Map<String, dynamic> data) {
milliliters = data['milliliters'];
time = data['time'];
}
类型推断
此外,无论您决定如何迭代 Map
实例,您都可以利用 Dart 的 type inference 稍微清理一下代码,所以(假设您正在迭代条目) loadSalesData
可以变成:
Future loadSalesData() async {
final jsonString = await getJsonFromFirebase();
final jsonResponse = json.decode(jsonString);
for (final i in jsonResponse.entries) {
chartData.add(SalesData.fromJson(i));
}
}
和getJsonFromFirebase
可以变成:
Future<String> getJsonFromFirebase() async {
final url = "http://localhost:8080/data.json";
final response = await http.get(Uri.parse(url));
return response.body;
}