[SOLVED] Flutter – How to show data from 2 objects in single Json file based on the same value

Issue

This Content is from Stack Overflow. Question asked by Joven Dev

I have JSON file with two objects which are food and instruction:

{
    "food": [
       {
           "id": "0001",
           "name": "Cake",
           "description":
              {
                "batter":
                   [ { "id": "instruction_1002", "type": "Chocolate" } ]
              }
       },
       {
           "id": "0002",
           "name": "Raised",
           "description":
             {
               "batter":
                [ { "id": "instruction_1003", "type": "Blueberry" } ]
             }
       }
    ],
    "instruction": [
       {
         "category": "instruction_1002",
         "content": "abc1234"
       },
       {
         "category": "instruction_1003",
         "content": "def56789"
       }
    ]
}

I want that when click on the name of the food, it will show instruction content based on the category that match them.
Example: Cake will have instruction content of abc1234 when Cake batter id = instruction.category
enter image description here

Below is the model file

class Post {
    List<Food>? food;
    List<Instruction>? instruction;
    Post({this.food, this.instruction});

    Post.fromJson(Map<String, dynamic> json) {
        if (json['food'] != null) {
            food = <Food>[];
            json['food'].forEach((v) {
                food!.add(new Food.fromJson(v));
            });
        }
        if (json['instruction'] != null) {
            instruction = <Instruction>[];
            json['instruction'].forEach((v) {
                instruction!.add(new Instruction.fromJson(v));
            });
        }
    }

    Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.food != null) {
            data['food'] = this.food!.map((v) => v.toJson()).toList();
        }
        if (this.instruction != null) {
          data['instruction'] = this.instruction!.map((v) => v.toJson()).toList();
        }
        return data;
    }
}

class Food {
  String? id;
  String? name;
  Description? description;

  Food({this.id, this.name, this.description});
  Food.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    description = json['description'] != null ? new Description.fromJson(json['description']) : null;
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    if (this.description != null) {
        data['description'] = this.description!.toJson();
    }
    return data;
  }
}

class Description {
    Description({
    List<Batter>? batter,
}) {
    _batter = batter;
}

Description.fromJson(dynamic json) {
    if (json['batter'] != null) {
        _batter = [];
        json['batter'].forEach((v) {
            _batter?.add(Batter.fromJson(v));
        });
    }
}
List<Batter>? _batter;
List<Batter>? get batter => _batter;

Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    if (_batter != null) {
       map['batter'] = _batter?.map((v) => v.toJson()).toList();
    }
    return map;
    }
}

class Batter {
  Batter({
    String? id,
    String? type,
  }) {
    _id = id;
    _type = type;
  }

  Batter.fromJson(dynamic json) {
    _id = json['id'];
    _type = json['type'];
  }
  String? _id;
  String? _type;

  String? get id => _id;
  String? get type => _type;

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map['id'] = _id;
    map['type'] = _type;
    return map;
  }
}

class Instruction {
  Instruction({
    String? category,
    String? content,
  }) {
    _category = category;
    _content = content;
  }

  Instruction.fromJson(dynamic json) {
    _category = json['category'];
    _content = json['content'];
  }
    String? _category;
    String? _content;

    String? get category => _category;
    String? get content => _content;

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map['category'] = _category;
    map['content'] = _content;
    return map;
  }
}

This is the main file:

import 'package:flutter/material.dart';
import '../model/post.dart';
import 'package:flutter/services.dart';
import 'dart:convert';

void main() {
  runApp(const MyApp());
}

Future<Post> getList() async {
  final getResponse = await rootBundle.loadString('assest/post.json');
  var data = jsonDecode(getResponse);
  return Post.fromJson(data);
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Post'),),
      body: Column(
        children: [
          Expanded(
            child: FutureBuilder<Post>(
              future: getList(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  var getText = snapshot.data!.food;
                  return SingleChildScrollView(
                    child: Wrap(
                      children: [
                        for (final word in getText!)
                          GestureDetector(
                            child: Text(word.name.toString()),
                            onTap: () {
                              Navigator.push( context, MaterialPageRoute(builder: (context) => foodDetail(food: word)) );
                            },
                          ),
                      ],
                    ),
                  );
                } else {
                  return Text('Loading');
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

In this main file, I was able to list all the food name, but after how to continue in foodDetail page? Please help.



Solution

Find the instruction in your onTap:

List<Instruction> instructions = myPost.instruction?.where((element) => element.category == selectedFood.description?.batter?[0].id).toList();

Pass the instruction also as param to foodDetail

foodDetail(food: word, instruction: instructions)


This Question was asked in StackOverflow by Joven Dev and Answered by Ozan Taskiran It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?