Convert JSON into POJO (Object) similar to android in Flutter
Solution 1
SO, after some tries with the json_serializable library, I came up with my own solution and it doesnt require any external library at all and works like a charm. This way i had to write less boilerplate code and i think is a clean way to do this.
Here's how to make the model
class SideMenuRes {
final int status;
final String message;
final List<SideMenuDatum> sideMenuData;
SideMenuRes({this.status, this.message, this.sideMenuData});
factory SideMenuRes.fromJson(Map json) {
return SideMenuRes(
status: json['status'],
message: json['message'],
sideMenuData: json['status'] == 200 ? (json['data'] as List).map((i) => new
SideMenuDatum.fromJson(i)).toList() : null,
);
}
}
class SideMenuDatum {
final Menu menu;
SideMenuDatum({this.menu});
factory SideMenuDatum.fromJson(Map json) {
return SideMenuDatum(
menu: Menu.fromJson(json['menu']),
);
}
}
class Menu {
final String megamenu_id;
final String language_id;
final String title;
final String description;
final List<SubMenu> subMenu;
Menu({this.megamenu_id, this.language_id, this.title, this.description, this.subMenu});
factory Menu.fromJson(Map json) {
return Menu(
megamenu_id: json['megamenu_id'],
language_id: json['language_id'],
title: json['title'],
description: json['description'],
subMenu: json['submenu'] != null ? (json['submenu'] as List).map((i) => new SubMenu.fromJson(i)).toList() : null
);
}
}
class SubMenu {
final Zero zero;
final List<SubSubMenu> subSubMenu;
SubMenu({this.zero, this.subSubMenu});
factory SubMenu.fromJson(Map json) {
return SubMenu(
zero: Zero.fromJson(json['0']),
subSubMenu: (json['subsubmenu'] as List).map((i) => new SubSubMenu.fromJson(i)).toList()
);
}
}
class Zero {
final Info info;
Zero({this.info});
factory Zero.fromJson(Map json) {
return Zero(
info: Info.fromJson(json['info']),
);
}
}
class SubSubMenu {
final InfoSub infoSub;
SubSubMenu({this.infoSub});
factory SubSubMenu.fromJson(Map json) {
return SubSubMenu(
infoSub: InfoSub.fromJson(json['infosub'])
);
}
}
class InfoSub {
final String megamenu_id;
final String language_id;
final String title;
final String description;
InfoSub({this.megamenu_id, this.language_id, this.title, this.description});
factory InfoSub.fromJson(Map json) {
return InfoSub(
megamenu_id: json['megamenu_id'],
language_id: json['language_id'],
title: json['title'],
description: json['description']
);
}
}
class Info {
final String megamenu_id;
final String language_id;
final String title;
final String description;
Info({this.megamenu_id, this.language_id, this.title, this.description});
factory Info.fromJson(Map json) {
return Info(
megamenu_id: json['megamenu_id'],
language_id: json['language_id'],
title: json['title'],
description: json['description']
);
}
}
And calling it like this
SubMenuRes subMenuRes = SubMenuRes.fromJson(response.data);
That's it!
Solution 2
Android Studio plugin: https://plugins.jetbrains.com/plugin/12562-jsontodart-json-to-dart-
Online: https://app.quicktype.io/?l=dart
Manually parse: https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51
Generate Dart classes from JSON
Convert JSON to Dart class
Generate Dart class from JSON or JSON-Schema.
Solution 3
json_serializable isn't that well documented, but it does exactly what you want, is easier to use and requires less boilerplate than built_value, especially when it comes to arrays.
import 'package:json_annotation/json_annotation.dart';
import 'dart:convert';
part 'school.g.dart';
@JsonSerializable()
class School {
final String name;
final int maxStudentCount;
final List<Student> students;
School(this.name, this.maxStudentCount, this.students);
factory School.fromJson(Map<String, dynamic> json) => _$SchoolFromJson(json);
Map<String, dynamic> toJson() => _$SchoolToJson(this);
}
@JsonSerializable()
class Student {
final String name;
final DateTime birthDate;
Student({this.name, this.birthDate});
factory Student.fromJson(Map<String, dynamic> json) => _$StudentFromJson(json);
Map<String, dynamic> toJson() => _$StudentToJson(this);
}
test() {
String jsonString = '''{
"name":"Trump University",
"maxStudentCount":9999,
"students":[
{
"name":"Peter Parker",
"birthDate":"1999-01-01T00:00:00.000Z"
}
]
}''';
final decodedJson = json.decode(jsonString);
final school = School.fromJson(decodedJson);
assert(school.students.length == 1);
}
It also supports enum serialization.
To generate the serialization code, run:
flutter packages pub run build_runner build
Solution 4
This can be done using built_value. Detailed documentation is available in this link.
You just have to write some boilerplate code and run this command flutter packages pub run build_runner build
.
Below is a sample class like POJO.
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'auth.g.dart';
abstract class Auth implements Built<Auth, AuthBuilder> {
static Serializer<Auth> get serializer => _$authSerializer;
String get currentServerTime;
int get defaultOrganization;
String get tokenExpiryTimeInMs;
bool get rememberMe;
int get failedLoginAttempts;
int get userId;
String get status;
String get token;
Auth._();
factory Auth([updates(AuthBuilder b)]) = _$Auth;
}
Below is the Serializer class:
library serializers;
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'auth/auth.dart';
part 'serializers.g.dart';
@SerializersFor(const [
Auth,
])
Serializers serializers = _$serializers;
Serializers standardSerializers =
(serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
Below is the code where conversion from JSON to Object takes place.
Auth auth = standardSerializers.deserializeWith(
Auth.serializer, json.decode(res.body)['user']);
Hope this helps.
Comments
-
Jaswant Singh over 1 year
I'm just trying to find a way to convert a json response (from a REST API) into POJO (As used in android) so that I can use the received data into my application as using Map wont be sufficient as the data i'm receiving is a little complex and contains 3 levels of arrays (arrays inside of arrays inside of arrays).
I'm using Dio library for api calls and i can make API call successfully and print the data on the console with no issues at all. Can anyone assist me in achieving this?
Below is the response i'm getting.
{ "status": 200, "message": "success", "data": [ { "menu": { "megamenu_id": "55", "language_id": "1", "title": "Mobiles", "description": "", "submenu": [ { "0": { "info": { "megamenu_id": "67", "language_id": "1", "title": "Mobile Phones", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "68", "language_id": "1", "title": "Android Phones", "description": "" } }, { "infosub": { "megamenu_id": "69", "language_id": "1", "title": "Smart Phones", "description": "" } }, { "infosub": { "megamenu_id": "70", "language_id": "1", "title": "Windows Phones", "description": "" } }, { "infosub": { "megamenu_id": "72", "language_id": "1", "title": "Basic Phones", "description": "" } }, { "infosub": { "megamenu_id": "73", "language_id": "1", "title": "Latest Mobiles", "description": "" } }, { "infosub": { "megamenu_id": "74", "language_id": "1", "title": "Upcoming Mobiles", "description": "" } } ] }, { "0": { "info": { "megamenu_id": "75", "language_id": "1", "title": "Brands", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "76", "language_id": "1", "title": "Samsung", "description": "" } }, { "infosub": { "megamenu_id": "77", "language_id": "1", "title": "Apple", "description": "" } }, { "infosub": { "megamenu_id": "78", "language_id": "1", "title": "Redmi", "description": "" } }, { "infosub": { "megamenu_id": "79", "language_id": "1", "title": "Nokia", "description": "" } }, { "infosub": { "megamenu_id": "81", "language_id": "1", "title": "Sony", "description": "" } }, { "infosub": { "megamenu_id": "82", "language_id": "1", "title": "Micromax", "description": "" } }, { "infosub": { "megamenu_id": "83", "language_id": "1", "title": "HTC", "description": "" } }, { "infosub": { "megamenu_id": "84", "language_id": "1", "title": "Motorola", "description": "" } }, { "infosub": { "megamenu_id": "85", "language_id": "1", "title": "Oppo", "description": "" } }, { "infosub": { "megamenu_id": "86", "language_id": "1", "title": "Vivo", "description": "" } }, { "infosub": { "megamenu_id": "87", "language_id": "1", "title": "Honor", "description": "" } }, { "infosub": { "megamenu_id": "88", "language_id": "1", "title": "Oneplus", "description": "" } } ] }, { "0": { "info": { "megamenu_id": "94", "language_id": "1", "title": "Mobile Accessories", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "95", "language_id": "1", "title": "Bluetooth Headsets", "description": "" } }, { "infosub": { "megamenu_id": "96", "language_id": "1", "title": "Mobile Chargers", "description": "" } }, { "infosub": { "megamenu_id": "97", "language_id": "1", "title": "Mobiles Cases & Covers", "description": "" } }, { "infosub": { "megamenu_id": "98", "language_id": "1", "title": "Screen Protector", "description": "" } }, { "infosub": { "megamenu_id": "99", "language_id": "1", "title": "Mobile Batteries", "description": "" } }, { "infosub": { "megamenu_id": "100", "language_id": "1", "title": "Headphones & Headsets", "description": "" } }, { "infosub": { "megamenu_id": "101", "language_id": "1", "title": "Memory Cards", "description": "" } }, { "infosub": { "megamenu_id": "102", "language_id": "1", "title": "Power Banks", "description": "" } }, { "infosub": { "megamenu_id": "103", "language_id": "1", "title": "Stylus", "description": "" } }, { "infosub": { "megamenu_id": "104", "language_id": "1", "title": "Mobile Docks", "description": "" } } ] }, { "0": { "info": { "megamenu_id": "107", "language_id": "1", "title": "Features", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "108", "language_id": "1", "title": "Dual Sim Phones", "description": "" } }, { "infosub": { "megamenu_id": "111", "language_id": "1", "title": "4GB Ram Mobiles", "description": "" } }, { "infosub": { "megamenu_id": "112", "language_id": "1", "title": "Rear Camera [13 MP]", "description": "" } }, { "infosub": { "megamenu_id": "113", "language_id": "1", "title": "Screen Size [4.5 - 5.2 Inch]", "description": "" } } ] } ] } }, { "menu": { "megamenu_id": "168", "language_id": "1", "title": "Fashion", "description": "", "submenu": [ { "0": { "info": { "megamenu_id": "169", "language_id": "1", "title": "Clothing", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "170", "language_id": "1", "title": "T-Shirts", "description": "" } }, { "infosub": { "megamenu_id": "171", "language_id": "1", "title": "Shirts", "description": "" } } ] }, { "0": { "info": { "megamenu_id": "178", "language_id": "1", "title": "Womens Clothing", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "187", "language_id": "1", "title": "Night Wear", "description": "" } }, { "infosub": { "megamenu_id": "188", "language_id": "1", "title": "Tunics", "description": "" } }, { "infosub": { "megamenu_id": "189", "language_id": "1", "title": "Kurtis", "description": "" } }, { "infosub": { "megamenu_id": "190", "language_id": "1", "title": "Sarees", "description": "" } }, { "infosub": { "megamenu_id": "191", "language_id": "1", "title": "Lehengas", "description": "" } }, { "infosub": { "megamenu_id": "192", "language_id": "1", "title": "Swimming Suit", "description": "" } } ] }, { "0": { "info": { "megamenu_id": "193", "language_id": "1", "title": "Men's Footwear", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "194", "language_id": "1", "title": "Shoes", "description": "" } }, { "infosub": { "megamenu_id": "195", "language_id": "1", "title": "Sneakers", "description": "" } }, { "infosub": { "megamenu_id": "196", "language_id": "1", "title": "Sandals & Floaters", "description": "" } }, { "infosub": { "megamenu_id": "197", "language_id": "1", "title": "Slippers & Flip Flops", "description": "" } }, { "infosub": { "megamenu_id": "198", "language_id": "1", "title": "Loafers", "description": "" } }, { "infosub": { "megamenu_id": "199", "language_id": "1", "title": "Boots", "description": "" } }, { "infosub": { "megamenu_id": "200", "language_id": "1", "title": "Shoe Care", "description": "" } } ] }, { "0": { "info": { "megamenu_id": "201", "language_id": "1", "title": "Women's Jewellery", "description": "" } }, "subsubmenu": [ { "infosub": { "megamenu_id": "202", "language_id": "1", "title": "Earrings", "description": "" } }, { "infosub": { "megamenu_id": "203", "language_id": "1", "title": "Bangles", "description": "" } }, { "infosub": { "megamenu_id": "204", "language_id": "1", "title": "Bracelets", "description": "" } }, { "infosub": { "megamenu_id": "205", "language_id": "1", "title": "Rings", "description": "" } } ] } ] } }, { "menu": { "megamenu_id": "220", "language_id": "1", "title": "Care", "description": "" } }, { "menu": { "megamenu_id": "221", "language_id": "1", "title": "Offers", "description": "" } }, { "menu": { "megamenu_id": "222", "language_id": "1", "title": "News", "description": "" } } ] }