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)