Reputation: 309
In a json file, there are two classes which are food and instruction. In the first page, a list of food name with a link will be display. When click on the food name, it will go to the second page where the instruction content related to the food will be display. Here the food -> batters -> batter id is equal to instruction -> category
So my question is how can I practically do or code it in flutter?
Below is the sample of json file:
{
"food": [
{
"id": "0001",
"name": "Cake",
"batters":
{
"batter":
[ { "id": "instruction_1002", "type": "Chocolate" } ]
}
},
{
"id": "0002",
"name": "Raised",
"batters":
{
"batter":
[ { "id": "instruction_1003", "type": "Blueberry" } ]
}
}
],
"instruction": [
{
"category": "instruction_1002",
"content": "abc1234"
},
{
"category": "instruction_1003",
"content": "def56789"
}
]
}
Upvotes: 0
Views: 352
Reputation: 5601
It seems your backend doesn't give you the relationship between those 2 so is up to you to encapuslate them and do the relationship yourself, the easiest way is yo have a Response object that decode your json:
class Response {
Response({
required this.food,
required this.instruction,
});
final List<Food> food;
final List<Instruction> instruction;
factory Response.fromJson(Map<String, dynamic> json) => Response(
food: List<Food>.from(json["food"].map((x) => Food.fromJson(x))),
instruction: List<Instruction>.from(json["instruction"].map((x) => Instruction.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"food": List<dynamic>.from(food.map((x) => x.toJson())),
"instruction": List<dynamic>.from(instruction.map((x) => x.toJson())),
};
}
class FoodResponse {
FoodResponse({
required this.id,
required this.name,
required this.batters,
});
final String id;
final String name;
final Batters batters;
factory FoodResponse.fromJson(Map<String, dynamic> json) => FoodResponse(
id: json["id"],
name: json["name"],
batters: Batters.fromJson(json["batters"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"batters": batters.toJson(),
};
}
class BattersResponse {
BattersResponse({required this.batter});
final List<Batter> batter;
factory BattersResponse.fromJson(Map<String, dynamic> json) => BattersResponse(
batter: List<Batter>.from(json["batter"].map((x) => Batter.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"batter": List<dynamic>.from(batter.map((x) => x.toJson())),
};
}
class BatterResponse {
BatterResponse({
required this.id,
required this.type,
});
final String id;
final String type;
factory BatterResponse.fromJson(Map<String, dynamic> json) => BatterResponse(
id: json["id"],
type: json["type"],
);
Map<String, dynamic> toJson() => {
"id": id,
"type": type,
};
}
class InstructionResponse {
InstructionResponse({
required this.category,
required this.content,
});
final String category;
final String content;
factory InstructionResponse.fromJson(Map<String, dynamic> json) => InstructionResponse(
category: json["category"],
content: json["content"],
);
Map<String, dynamic> toJson() => {
"category": category,
"content": content,
};
}
Now you only need to parse from the response object to your domain (what you actually want)
class Model {
final List<Food> food;
const Model({this.food = const <Food>[]});
factory Model.fromResponse(Response response) {
final foodList = response.food.toList();
final instructionsResponse = response.instruction.toList();
final List<Food> items = [];
for (int f = 0; f < foodList.length; f++) {
final List<Instruction> instructions = [];
final food = foodList[f];
food.batters.batter.forEach((b) {
for (int i = 0; i < instructionsResponse.length; i++) {
final singleInstruction = instructionsResponse[i];
if (singleInstruction.category == b.id) {
final Instruction instruction = Instruction(
id: b.id,
content: singleInstruction.content,
ingredient: b.type,
);
instructions.add(instruction);
}
}
items.add(Food(id: food.id, name: food.name, instructions: instructions));
});
}
return Model(food: items);
}
}
class Food {
final String id;
final String name;
final List<Instruction> instructions;
const Food({
required this.id,
required this.name,
this.instructions = const <Instruction>[],
});
}
class Instruction {
final String id;
final String content;
final String ingredient;
const Instruction({
required this.id,
required this.content,
required this.ingredient,
});
}
Now you can use Model in your UI which have both food and their instructions related. This is maybe not the best approach for simple apps, but when your app starts to grow it will be simplier to mantain your Model if your backend changess the format of the json. At the end all this should be in an state management that simplifies the relation between your UI and your repositories (backend)
Upvotes: 1
Reputation: 1191
The quickest way to do it from a known JSON is to use app.quicktype.io, paste your json, select dart and have it translate into classes for you!
Upvotes: 0
Reputation: 323
what do you want, that's very easy just define 2 classes and decode the JSON file and after that, store that into the state management, and finally use it
Upvotes: 0