Flutter model for nested json

2,664

Solution 1

Here is the solution with the model I'm currently using:

model.dart

import 'dart:convert';

List<User> userFromJson(String str) =>
    List<User>.from(json.decode(str).map((x) => User.fromJson(x)));

String userToJson(List<User> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class User {
  User({
    this.name,
    this.surname,
    this.areaName,
    this.details,
  });

  String name;
  String surname;
  String areaName;
  String details;

  factory User.fromJson(Map<String, dynamic> json) => User(
        name: json["name"],
        surname: json["surname"],
        areaName: json["areaName"],
        details: json["details"],
      );

  Map<String, dynamic> toJson() => {
        "name": name,
        "surname": surname,
        "areaName": areaName,
        "details": details,
      };
}

Details DetailsFromJson(String str) => Details.fromJson(json.decode(str));

String DetailsToJson(Details data) => json.encode(data.toJson());

class Details {
  Details({
    this.work,
    this.address,
  });

  Work work;
  Address address;

  factory Details.fromJson(Map<String, dynamic> json) => Details(
        work: Work.fromJson(json["work"]),
        address: Address.fromJson(json["address"]),
      );

  Map<String, dynamic> toJson() => {
        "work": work.toJson(),
        "address": address.toJson(),
      };
}

class Address {
  Address({
    this.street,
    this.city,
  });

  String street;
  String city;

  factory Address.fromJson(Map<String, dynamic> json) => Address(
        street: json["street"],
        city: json["city"],
      );

  Map<String, dynamic> toJson() => {
        "street": street,
        "city": city,
      };
}

class Work {
  Work({
    this.salary,
    this.company,
  });

  String salary;
  String company;

  factory Work.fromJson(Map<String, dynamic> json) => Work(
        salary: json["salary"],
        company: json["company"],
      );

  Map<String, dynamic> toJson() => {
        "salary": salary,
        "company": company,
      };
}

Thank you for the help!

Solution 2

Please refer to this link to get the model for your json.

https://app.quicktype.io/

Add your json, select your language and you can have your model.

Share:
2,664
SpaghettiFunk
Author by

SpaghettiFunk

Updated on December 27, 2022

Comments

  • SpaghettiFunk
    SpaghettiFunk over 1 year

    I'm creating a flutter app for data visualization. There will be 3 pages:

    • Filter page for filter criteria,
    • List page for visualizing serach result,
    • Details page.

    I will receive a json like this:

    data.json

    [
        {
            "name": "Jhon",
            "surname": "Walker",
            "details": "{\"work\":{\"salary\":\"116\",\"company\":\"evolution\",\"image\":\"http://image.jpg\"},\"address\":{\"street\":\"grand station\",\"city\":\"salt lake\"}}"    
        },
        {
            "name": "Alan",
            "surname": "Turing",
            "details": "{\"work\":{\"salary\":\"116\",\"company\":\"evolution\",\"image\":\"http://image.jpg\"},\"address\":{\"street\":\"grand station\",\"city\":\"salt lake\"}}"    
        }
    ]
    

    It could be a really long list.

    I have already posted a question here about my code for this app which is not working, here is the discussion

    Flutter app error

    So now I' m asking a different question. Which is the best model for this json structure? I need to have direct access to all the fields in the details object. I would like to have the ability to directly get the field salary or company. I need to have access to the image field which will contain a url for an image to display in the app. In the linked post I have generated a model using serialization and built_value. It is not working in the code, I still get the error:

    type String is not a subtype of type 'Map<String, dynamic>' in type cast
    

    And no one solutions that I find online seems to work.

    I have created another model without nested objects, this is how I made it: model.dart

    class User {
    
      String name;
    
      String surname;
    
      String details;
    
    
      User({
        this.name,
        this.surname,
        this.details,
      });
    
    
      factory User.fromJson(Map<String, dynamic> json) => User(
        name: json["name"],
        surname: json["surname"],
        details: json["details"],
      );
    
      Map<String, dynamic> toJson() => {
        "name": name,
        "surname": surname,
        "details": details,
      };
    }
    

    With this model I' m able to display the data on a ListView but the details field is one only big string and I have no idea about how to access the fields in the details object. I can only think to regualr expression but it sounds kind of tricky, and why I should use regualr expression when I have JSON?

    Which model is the best for this json? Should I change path? Do you have any advice for a better data model, or maybe a solution for using the data model correctly from the discussion that I linked? I' m not asking the same question, I' m just trying to find the right solution for accessing deatils fields using standard json.

    Thank you!

  • SpaghettiFunk
    SpaghettiFunk over 3 years
    Whit which model? Because with both models there is an error: "The argument type String can' t be assigned to the parameter type Map<String,Dynamic>. For now my json is loaded into a String.
  • fartem
    fartem over 3 years
    For example: you can create a widget for user class and pass user class instance to it. In widget's internals you can change a values of concrete user and change UI by calling setState.
  • SpaghettiFunk
    SpaghettiFunk over 3 years
    But I have to pass a list of User, for visualizing the user list and then, in the Details page, I will pass an user. I' m wrong?
  • SpaghettiFunk
    SpaghettiFunk over 3 years
    Still have no clue of what model is and how to make it work. I have generated the model by reading the documentation of the page you linked, but I' m unable to create a list of User and display it.
  • fartem
    fartem over 3 years
    After you have a list of users you can manipulate them. You can create ListTile object for each user from a collection by users.map((user) => ListTile(title: Text(user.name))) and pass list of widgets to Column class (just for example).
  • SpaghettiFunk
    SpaghettiFunk over 3 years
    I have already used it. But the details field will be one only string. However I see that this string is without the escape charter after the decode. If I create a model with quicktype for ExtraData I could make this a string and decode with this model for the ExtraData?