How to use generics and list of generics with json serialization in Dart?
Here's a example about that
https://github.com/dart-lang/json_serializable/blob/master/example/lib/json_converter_example.dart
// json_converter_example.dart
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file// for details. All rights reserved. Use of this source code is governed by a// BSD-style license that can be found in the LICENSE file.import 'package:json_annotation/json_annotation.dart';part 'json_converter_example.g.dart';@JsonSerializable()class GenericCollection<T> { @JsonKey(name: 'page') final int page; @JsonKey(name: 'total_results') final int totalResults; @JsonKey(name: 'total_pages') final int totalPages; @JsonKey(name: 'results') @_Converter() final List<T> results; GenericCollection( {this.page, this.totalResults, this.totalPages, this.results}); factory GenericCollection.fromJson(Map<String, dynamic> json) => _$GenericCollectionFromJson<T>(json); Map<String, dynamic> toJson() => _$GenericCollectionToJson(this);}class _Converter<T> implements JsonConverter<T, Object> { const _Converter(); @override T fromJson(Object json) { if (json is Map<String, dynamic> && json.containsKey('name') && json.containsKey('size')) { return CustomResult.fromJson(json) as T; } if (json is Map<String, dynamic> && json.containsKey('name') && json.containsKey('lastname')) { return Person.fromJson(json) as T; } // This will only work if `json` is a native JSON type: // num, String, bool, null, etc // *and* is assignable to `T`. return json as T; } @override Object toJson(T object) { // This will only work if `object` is a native JSON type: // num, String, bool, null, etc // Or if it has a `toJson()` function`. return object; }}@JsonSerializable()class CustomResult { final String name; final int size; CustomResult(this.name, this.size); factory CustomResult.fromJson(Map<String, dynamic> json) => _$CustomResultFromJson(json); Map<String, dynamic> toJson() => _$CustomResultToJson(this); @override bool operator ==(Object other) => other is CustomResult && other.name == name && other.size == size; @override int get hashCode => name.hashCode * 31 ^ size.hashCode;}@JsonSerializable()class Person { final String name; final String lastname; Person(this.name, this.lastname); factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json); Map<String, dynamic> toJson() => _$PersonToJson(this); @override bool operator ==(Object other) => other is Person && other.name == name && other.lastname == lastname;}
// main.dart
import './json_converter_example.dart';import 'dart:convert';final jsonStringCustom = '''{"page":1,"total_results":10,"total_pages":200,"results":[{"name":"Something","size":80},{"name":"Something 2","size":200}]}''';final jsonStringPerson = '''{"page":2,"total_results":2,"total_pages":300,"results":[{"name":"Arya","lastname":"Stark"},{"name":"Night","lastname":"King"}]}''';void main() { // Encode CustomResult List<CustomResult> results; results = [CustomResult("Mark", 223), CustomResult("Albert", 200)]; // var customResult = List<CustomResult> data; var jsonData = GenericCollection<CustomResult>( page: 1, totalPages: 200, totalResults: 10, results: results); print({'JsonString', json.encode(jsonData)}); // Decode CustomResult final genericCollectionCustom = GenericCollection<CustomResult>.fromJson(json.decode(jsonStringCustom)); print({'name', genericCollectionCustom.results[0].name}); // Encode Person List<Person> person; person = [Person("Arya", "Stark"), Person("Night", "King")]; var jsonDataPerson = GenericCollection<Person>( page: 2, totalPages: 300, totalResults: 2, results: person); print({'JsonStringPerson', json.encode(jsonDataPerson)}); // Decode Person final genericCollectionPerson = GenericCollection<Person>.fromJson(json.decode(jsonStringPerson)); print({'name', genericCollectionPerson.results[0].name});}
the result it's
{JsonStringCustom, {"page":1,"total_results":10,"total_pages":200,"results":[{"name":"Mark","size":223},{"name":"Albert","size":200}]}}{name, Something}{JsonStringPerson, {"page":2,"total_results":2,"total_pages":300,"results":[{"name":"Arya","lastname":"Stark"},{"name":"Night","lastname":"King"}]}}{name, Arya}
here is the my proper solution perfectly worked for me.
class Paginate<T> { int from; int index; int size; int count; int pages; List<T> items; bool hasPrevious; bool hasNext; Paginate( {this.index, this.size, this.count, this.from, this.hasNext, this.hasPrevious, this.items, this.pages}); factory Paginate.fromJson(Map<String,dynamic> json,Function fromJsonModel){ final items = json['items'].cast<Map<String, dynamic>>(); return Paginate<T>( from: json['from'], index: json['index'], size: json['size'], count: json['count'], pages: json['pages'], hasPrevious: json['hasPrevious'], hasNext: json['hasNext'], items: new List<T>.from(items.map((itemsJson) => fromJsonModel(itemsJson))) ); }}
Lets say we are going to use flight model paginate model. here you must configure the flight list.
class Flight { String flightScheduleId; String flightId; String flightNo; String flightDate; String flightTime; Flight( {this.flightScheduleId, this.flightId, this.flightNo, this.flightDate, this.flightTime}); factory Flight.fromJson(Map<String, dynamic> parsedJson) { var dateFormatter = new DateFormat(Constants.COMMON_DATE_FORMAT); var timeFormatter = new DateFormat(Constants.COMMON_TIME_FORMAT); var parsedDate = DateTime.parse(parsedJson['flightDepartureTime']); String formattedDate = dateFormatter.format(parsedDate); String formattedTime = timeFormatter.format(parsedDate); return Flight( flightScheduleId: parsedJson['id'], flightId: parsedJson['flightLayoutId'], flightNo: parsedJson['outboundFlightName'], flightDate: formattedDate, flightTime: formattedTime, } // Magic goes here. you can use this function to from json method. static Flight fromJsonModel(Map<String, dynamic> json) => Flight.fromJson(json);}
-> Here you can use,
Paginate<Flight>.fromJson(responses, Flight.fromJsonModel);