0

I'm not able to convert server response to model class. The following is my code.

void main() {

  //JSON to parse
  var strJson = """{
  \"person\": [
      {\"name\": \"Mahendra\", \"age\": 28},
      {\"name\": \"Test\", \"age\": 25}
    ]
  }""";

  var data = json.decode(strJson);
  print("json: $data");

  var result = PersonResponse<Person>.fromJSON(data);
  print("result: ${result.persons}");

}

Model Class

class Person {
  String name;
  int age;

  Person.fromJSON(Map json) {
    this.name = json["name"];
    this.age = json["age"];
  }
}

class PersonResponse<T> {

  List<T> persons;

  PersonResponse.fromJSON(Map json) {
    this.persons = json["person"];
  }
}

When I run this code I'm not able to convert server response to model class. Getting following error...

Unhandled Exception: type List<dynamic> is not a subtype of type List<Person>

Whats wrong with my code. Any suggestions?

Mahendra
  • 8,448
  • 3
  • 33
  • 56

3 Answers3

1

try

// To parse this JSON data, do
//
//     final person = personFromJson(jsonString);

import 'dart:convert';

Person personFromJson(String str) => Person.fromJson(json.decode(str));

String personToJson(Person data) => json.encode(data.toJson());

class Person {
    List<PersonElement> person;

    Person({
        this.person,
    });

    factory Person.fromJson(Map<String, dynamic> json) => Person(
        person: List<PersonElement>.from(json["person"].map((x) => PersonElement.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "person": List<dynamic>.from(person.map((x) => x.toJson())),
    };
}

class PersonElement {
    String name;
    int age;

    PersonElement({
        this.name,
        this.age,
    });

    factory PersonElement.fromJson(Map<String, dynamic> json) => PersonElement(
        name: json["name"],
        age: json["age"],
    );

    Map<String, dynamic> toJson() => {
        "name": name,
        "age": age,
    };
}
Dev
  • 6,628
  • 2
  • 25
  • 34
1

I found 3 options:

  • You can either abandon usage of generics and replace List<T> persons; with List<dynamic> persons;. Your code will actually work with only this change.

  • You can abandon usage of generics and replace List<T> persons; with List<Person> and map it in fromJson.

class PersonResponse {

  List<Person> persons;

  PersonResponse.fromJSON(Map json) {
    List<dynamic> list = json["person"];
    persons = list.map((element) => Person.fromJSON(element)).toList();
  }
}
  • Keep generics but restrict in to something serializable, to something like this:
class PersonResponse<T extends JsonSerializable> {
  List<T> persons;

  PersonResponse.fromJSON(Map json) {
    List<dynamic> list = json["person"];
    persons = list.map((element) => T.fromJSON(element)).toList();
  }
}
pr0gramist
  • 8,305
  • 2
  • 36
  • 48
0

Don't convert JSON into dart object manually. Because some time JSON response are very complex So it may happen you can write incorrect data type. So always use Online JSON to Dart Convertor. It is free to use. It will reduce the chance of error.

Kamal Bunkar
  • 1,354
  • 1
  • 16
  • 20