#api #flutter #dart
Вопрос:
Я использую https://app.quicktype.io/ для создания модели данных. И я анализирую модель следующим образом:
var data = welcomeFromJson(response.body.toString());
return data;
——обновление——-
Я хочу объединить следующие две модели в одну (интегрировать питание в рецепт): Но я сомневаюсь, правильно ли я пишу для модели питания.
class Recipe {
final String name;
final String images;
final String totalTime;
Recipe({this.name, this.images, this.totalTime});
factory Recipe.fromJson(dynamic json) {
// var nutritionList = json['nutrition'] as List;
// List<Nutrition> nutriList =
// nutritionList.map((nutri) => Nutrition.fromJson(nutri)).toList();
return Recipe(
name: json['details']['name'] as String,
images: json['details']['images'][0]['hostedLargeUrl'] as String,
totalTime: json['details']['totalTime'] as String);
// nutrition: nutriList);
}
static List<Recipe> recipesFromSnapshot(List snapshot) {
return snapshot.map((data) => Recipe.fromJson(data)).toList();
}
}
class Nutrition {
final double kCal;
final double fatKCal;
final double proteinGram;
final double carbsGram;
Nutrition({this.kCal, this.fatKCal, this.proteinGram, this.carbsGram});
factory Nutrition.fromJson(dynamic json) {
return Nutrition(
kCal: json['nutrition']['nutritionEstimates'][12]['value'] as double,
fatKCal: json['nutrition']['nutritionEstimates'][0]['value'] as double,
proteinGram:
json['nutrition']['nutritionEstimates'][6]['value'] as double,
carbsGram: json['nutrition']['nutritionEstimates'][7]['value'] as double,
);
}
static List<Nutrition> nutritionFromSnapshot(snapshot) {
return snapshot.map((data) => Nutrition.fromJson(data)).toList();
}
}
Следующее является частью JSON.
{"feed": [
{
"content": {
"details": {
"totalTime": "20 min",
"images": [
{
"hostedLargeUrl": "https://lh3.googleusercontent.com/ei5eF1LRFkkcekhjdR_8XgOqgdjpomf-rda_vvh7jIauCgLlEWORINSKMRR6I6iTcxxZL9riJwFqKMvK0ixS0xwnRHGMY4I5Zw=s360",
"resizableImageUrl": "https://lh3.googleusercontent.com/GrQx2bXJfqWsY5J9YVQdjixy0Mi675_bCLmV10_jSPJeVLLBgHuBk3or8gb95lsMYTmZMiYT8omiZYdB_64crHtCxVdL8dEpKd1m",
"resizableImageHeight": 1438,
"resizableImageWidth": 1438
}
],
"name": "Easy Korean Sticky Chicken"
},
"nutrition": {
"mobileSectionName": "Nutrition",
"nutritionEstimates": [
{
"attribute": "FAT_KCAL",
"value": 170.00,
"unit": {
"name": "calorie",
"abbreviation": "kcal",
"plural": "calories",
"decimal": true
},
"display": {
"value": 170.0,
"unit": null,
"percentDailyValue": null
}
},
{
"attribute": "PROCNT",
"value": 35.00,
"unit": {
"name": "gram",
"abbreviation": "g",
"plural": "grams",
"decimal": true
},
"display": {
"value": 35.0,
"unit": "g",
"percentDailyValue": null
}
},
{
"attribute": "CHOCDF",
"value": 12.00,
"unit": {
"name": "gram",
"abbreviation": "g",
"plural": "grams",
"decimal": true
},
"display": {
"value": 12.0,
"unit": "g",
"percentDailyValue": 4
}
},
{
"attribute": "ENERC_KCAL",
"value": 371.00,
"unit": {
"name": "calorie",
"abbreviation": "kcal",
"plural": "calories",
"decimal": true
},
"display": {
"value": 370.0,
"unit": null,
"percentDailyValue": null
}
},
{
"attribute": "FAT",
"value": 19.00,
"unit": {
"name": "gram",
"abbreviation": "g",
"plural": "grams",
"decimal": true
},
"display": {
"value": 19.0,
"unit": "g",
"percentDailyValue": 29}}]}}}]}
Наконец, я хочу использовать следующее для извлечения данных. Не уверен, что это правильный путь.
var data = jsonDecode(response.body);
List _temp = [];
for (var i in data['feed']) {
_temp.add(i['content']);
}
return Nutrition.nutritionFromSnapshot(_temp);
Такой вложенный json — это действительно головная боль. Я проверял несколько раз, и он вернет ошибку
Performing hot restart...
Syncing files to device iPhone 11...
Restarted application in 831ms.
[GETX] Instance "ProductController" has been created
[GETX] Instance "ProductController" has been initialized
[VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 12
#0 List.[] (dart:core-patch/growable_array.dart:254:60)
#1 new Nutrition.fromJson (package:flutter_budget_ui/models/yummly_model.dart:32:52)
#2 Nutrition.nutritionFromSnapshot.<anonymous closure> (package:flutter_budget_ui/models/yummly_model.dart:40:45)
#3 MappedListIterable.elementAt (dart:_internal/iterable.dart:411:31)
#4 ListIterator.moveNext (dart:_internal/iterable.dart:340:26)
#5 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
#6 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
#7 new List.of (dart:core-patch/array_patch.dart:50:28)
#8 ListIterable.toList (dart:_internal/iterable.dart:211:44)
#9 Nutrition.nutritionFromSnapshot (package:flutter_budget_ui/models/yummly_model.dart:40:61)
#10 RemoteServices.getRecipe (package:flutter_budget_ui/helpers/remote_service.<…>
Ответ №1:
Согласно вашему JSON, ваш класс модели должен выглядеть следующим образом
class ModelClass {
List<Feed> feed;
ModelClass({this.feed});
ModelClass.fromJson(Map<String, dynamic> json) {
if (json['feed'] != null) {
feed = new List<Feed>();
json['feed'].forEach((v) {
feed.add(new Feed.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.feed != null) {
data['feed'] = this.feed.map((v) => v.toJson()).toList();
}
return data;
}
}
class Feed {
Content content;
Feed({this.content});
Feed.fromJson(Map<String, dynamic> json) {
content =
json['content'] != null ? new Content.fromJson(json['content']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.content != null) {
data['content'] = this.content.toJson();
}
return data;
}
}
class Content {
Details details;
Nutrition nutrition;
Content({this.details, this.nutrition});
Content.fromJson(Map<String, dynamic> json) {
details =
json['details'] != null ? new Details.fromJson(json['details']) : null;
nutrition = json['nutrition'] != null
? new Nutrition.fromJson(json['nutrition'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.details != null) {
data['details'] = this.details.toJson();
}
if (this.nutrition != null) {
data['nutrition'] = this.nutrition.toJson();
}
return data;
}
}
class Details {
String totalTime;
List<Images> images;
String name;
Details({this.totalTime, this.images, this.name});
Details.fromJson(Map<String, dynamic> json) {
totalTime = json['totalTime'];
if (json['images'] != null) {
images = new List<Images>();
json['images'].forEach((v) {
images.add(new Images.fromJson(v));
});
}
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['totalTime'] = this.totalTime;
if (this.images != null) {
data['images'] = this.images.map((v) => v.toJson()).toList();
}
data['name'] = this.name;
return data;
}
}
class Images {
String hostedLargeUrl;
String resizableImageUrl;
int resizableImageHeight;
int resizableImageWidth;
Images(
{this.hostedLargeUrl,
this.resizableImageUrl,
this.resizableImageHeight,
this.resizableImageWidth});
Images.fromJson(Map<String, dynamic> json) {
hostedLargeUrl = json['hostedLargeUrl'];
resizableImageUrl = json['resizableImageUrl'];
resizableImageHeight = json['resizableImageHeight'];
resizableImageWidth = json['resizableImageWidth'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['hostedLargeUrl'] = this.hostedLargeUrl;
data['resizableImageUrl'] = this.resizableImageUrl;
data['resizableImageHeight'] = this.resizableImageHeight;
data['resizableImageWidth'] = this.resizableImageWidth;
return data;
}
}
class Nutrition {
String mobileSectionName;
List<NutritionEstimates> nutritionEstimates;
Nutrition({this.mobileSectionName, this.nutritionEstimates});
Nutrition.fromJson(Map<String, dynamic> json) {
mobileSectionName = json['mobileSectionName'];
if (json['nutritionEstimates'] != null) {
nutritionEstimates = new List<NutritionEstimates>();
json['nutritionEstimates'].forEach((v) {
nutritionEstimates.add(new NutritionEstimates.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['mobileSectionName'] = this.mobileSectionName;
if (this.nutritionEstimates != null) {
data['nutritionEstimates'] =
this.nutritionEstimates.map((v) => v.toJson()).toList();
}
return data;
}
}
class NutritionEstimates {
String attribute;
int value;
Unit unit;
Display display;
NutritionEstimates({this.attribute, this.value, this.unit, this.display});
NutritionEstimates.fromJson(Map<String, dynamic> json) {
attribute = json['attribute'];
value = json['value'];
unit = json['unit'] != null ? new Unit.fromJson(json['unit']) : null;
display =
json['display'] != null ? new Display.fromJson(json['display']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['attribute'] = this.attribute;
data['value'] = this.value;
if (this.unit != null) {
data['unit'] = this.unit.toJson();
}
if (this.display != null) {
data['display'] = this.display.toJson();
}
return data;
}
}
class Unit {
String name;
String abbreviation;
String plural;
bool decimal;
Unit({this.name, this.abbreviation, this.plural, this.decimal});
Unit.fromJson(Map<String, dynamic> json) {
name = json['name'];
abbreviation = json['abbreviation'];
plural = json['plural'];
decimal = json['decimal'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['abbreviation'] = this.abbreviation;
data['plural'] = this.plural;
data['decimal'] = this.decimal;
return data;
}
}
class Display {
int value;
String unit;
int percentDailyValue;
Display({this.value, this.unit, this.percentDailyValue});
Display.fromJson(Map<String, dynamic> json) {
value = json['value'];
unit = json['unit'];
percentDailyValue = json['percentDailyValue'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['value'] = this.value;
data['unit'] = this.unit;
data['percentDailyValue'] = this.percentDailyValue;
return data;
}
}
Используйте его, как:
var data = jsonDecode(response.body);
ModelClass modelClass = ModelClass.fromJson(data);
Отсюда вы можете легко преобразовать свой JSON в класс dart.
Комментарии:
1. Спасибо тебе, Типу. Но я получил следующую ошибку: [VERBOSE-2:ui_dart_state.cc(186)] Необработанное исключение: тип «Класс моделей» не является подтипом типа » Список<динамический>»