I have a common response structure from http request like this
class CommonResponse<T> {
int total;
List<T> data;
bool success;
CommonResponse({this.total, this.data, this.success});
CommonResponse.fromJson(Map<String, dynamic> json) {
total = json['total'];
data = json['data'];
success = json['success'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['total'] = this.total;
data['data'] = this.data;
data['success'] = this.success;
}
}
Now I need to parse the generic data. For example I am getting list of zones inside data object in CommonResponse
class Zone {
bool active;
String id;
String name;
Zone({this.active, this.id, this.name});
Zone.fromJson(Map<String, dynamic> json) {
this.active = json['active'];
this.id = json['id'];
this.name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['active'] = this.active;
data['id'] = this.id;
data['name'] = this.name;
}
}
How to get list of zones?
var response = {
"data": [
{
"active": true,
"created_on": "2020-03-12T09:56:11+00:00",
"description": "For Testing",
"id": "b17627eb-8a39-4230-80fe-ebed77f7e0e2",
"name": "Office",
"updated_on": "2020-03-19T12:26:16+00:00"
}
],
"success": true,
"total": 1
};
CommonResponse<Zone> common = CommonResponse.fromJson(response);
print(common.data);
This is what i tried. I am getting perfect response but am getting error getting list of Zone
. Error is cannot convert List<dynamic>
to Zone
.
To generate proper transformation from and to json you can use json_serializable package. It supports generic arguments via @JsonSerializable(genericArgumentFactories: true)
.
First of all let's do small code refactor:
Move Zone
class into zone.dart
:
import 'package:json_annotation/json_annotation.dart';
part 'zone.g.dart';
@JsonSerializable()
class Zone {
bool active;
String id;
String name;
Zone({this.active, this.id, this.name});
factory Zone.fromJson(Map<String, dynamic> json) => _$ZoneFromJson(json);
Map<String, dynamic> toJson() => _$ZoneToJson(this);
}
CommonResponse
class to common_response.dart
import 'package:json_annotation/json_annotation.dart';
part 'common_response.g.dart';
@JsonSerializable(genericArgumentFactories: true)
class CommonResponse<T> {
int total;
List<T> data;
bool success;
CommonResponse({this.total, this.data, this.success});
factory CommonResponse.fromJson(
Map<String, dynamic> json,
T Function(Object json) fromJsonT,
) =>
_$CommonResponseFromJson(json, fromJsonT);
Map<String, dynamic> toJson(Object Function(T value) toJsonT) =>
_$CommonResponseToJson(this, toJsonT);
}
And run flutter pub run build_runner build
.
The output is as below:
zone.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'zone.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Zone _$ZoneFromJson(Map<String, dynamic> json) {
return Zone(
active: json['active'] as bool,
id: json['id'] as String,
name: json['name'] as String,
);
}
Map<String, dynamic> _$ZoneToJson(Zone instance) => <String, dynamic>{
'active': instance.active,
'id': instance.id,
'name': instance.name,
};
common_response.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'common_response.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CommonResponse<T> _$CommonResponseFromJson<T>(
Map<String, dynamic> json,
T Function(Object json) fromJsonT,
) {
return CommonResponse<T>(
total: json['total'] as int,
data: (json['data'] as List)?.map(fromJsonT)?.toList(),
success: json['success'] as bool,
);
}
Map<String, dynamic> _$CommonResponseToJson<T>(
CommonResponse<T> instance,
Object Function(T value) toJsonT,
) =>
<String, dynamic>{
'total': instance.total,
'data': instance.data?.map(toJsonT)?.toList(),
'success': instance.success,
};
Sample usage:
import 'common_response.dart';
import 'zone.dart';
void main() {
var response = {
'data': [
{
'active': true,
'created_on': '2020-03-12T09:56:11+00:00',
'description': 'For Testing',
'id': 'b17627eb-8a39-4230-80fe-ebed77f7e0e2',
'name': 'Office',
'updated_on': '2020-03-19T12:26:16+00:00'
}
],
'success': true,
'total': 1
};
var common =
CommonResponse<Zone>.fromJson(response, (data) => Zone.fromJson(data));
for (var zone in common.data) {
print(zone.id);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With