Generics in Dart/Flutter

 1. Define the data model class representing your JSON structure. In this case, you have a JSON response with three fields: "status," "message," and "data." The "data" field contains an array of objects having "id" and "name" fields. Here's an example of how you can define the data model:

class ApiResponse<T> { int status; String message; T data; ApiResponse({required this.status, required this.message, required this.data}); factory ApiResponse.fromJson(Map<String, dynamic> json, Function fromJsonT) { return ApiResponse( status: json['status'], message: json['message'], data: fromJsonT(json['data']), ); } } class DataModel { int id; String name; DataModel({required this.id, required this.name}); factory DataModel.fromJson(Map<String, dynamic> json) { return DataModel( id: json['id'], name: json['name'], ); } }



2. Parse the JSON response using the defined model classes. You can create a function that converts the JSON into the desired model using generics:

ApiResponse<T> parseJson<T>(String jsonString, Function fromJsonT) { final jsonData = json.decode(jsonString); return ApiResponse.fromJson(jsonData, fromJsonT); }


3. Invoke the parsing function by passing the JSON response and the model class to generate the desired object:

String jsonResponse = ''' { "status":"200", "message":"Data fetch success", "data":[ { "id":0, "name":"Soton" } ] } '''; ApiResponse<List<DataModel>> response = parseJson<List<DataModel>>( jsonResponse, (data) => List<DataModel>.from(data.map((x) => DataModel.fromJson(x))), ); print(response.status); // 200 print(response.message); // Data fetch success print(response.data[0].id); // 0 print(response.data[0].name); // Soton


By using generics and the defined model classes, you can parse your JSON response into Flutter objects while maintaining type safety and reusability.




final responseStr = await postService(payload: {
"email": "jobayer.m360ict@gmail.com",
"password": "123456789"
});


ApiResponse<UsersModel> response = parseJson<UsersModel>(
responseStr,
(data) => UsersModel.fromJson(data),
);

print(response.success); // 200
print(response.message); // Data fetch success
print(response.data?.name); // 0
print(response.data?.email); // Soton


import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;

Future<String> postService({required Map<String,String> payload}) async {
Uri url = Uri.parse("https://server.evaluation360.world/api/v1/auth/upc/login");

final Map<String, String> header = {
"Content-Type": "application/json",
};


try {
final response =
await http.post(url, body: jsonEncode(payload), headers: header);


return response.body;

} on TimeoutException catch (e) {
return '''
{
"status": "300",
"message": "Data fetch timeout",
"data": null
}
''';
} on SocketException catch (e) {

return '''
{
"status": "400",
"message": "Data fetch failed no internet",
"data": null
}
''';
} catch (e) {

return '''
{
"status": "500",
"message": "Data fetch failed",
"data": null
}
''';
}
}



// To parse this JSON data, do
//
// final usersModel = usersModelFromJson(jsonString);

// import 'dart:convert';

// UsersModel usersModelFromJson(String str) => UsersModel.fromJson(json.decode(str));

// String usersModelToJson(UsersModel data) => json.encode(data.toJson());

class UsersModel {
int? id;
String? name;
dynamic phone;
String? email;
dynamic photo;
dynamic nidFront;
dynamic nidBack;
dynamic country;
dynamic city;
dynamic address;
String? status;
DateTime? createdAt;

UsersModel({
this.id,
this.name,
this.phone,
this.email,
this.photo,
this.nidFront,
this.nidBack,
this.country,
this.city,
this.address,
this.status,
this.createdAt,
});

factory UsersModel.fromJson(Map<String, dynamic> json) => UsersModel(
id: json["id"],
name: json["name"],
phone: json["phone"],
email: json["email"],
photo: json["photo"],
nidFront: json["nid_front"],
nidBack: json["nid_back"],
country: json["country"],
city: json["city"],
address: json["address"],
status: json["status"],
createdAt: json["created_at"] == null ? null : DateTime.parse(json["created_at"]),
);

}



class ApiResponse<T> {
bool? success;
String? message;
T? data;

ApiResponse({this.success, this.message, this.data});

factory ApiResponse.fromJson(Map<String, dynamic> json, Function fromJsonT) {
return ApiResponse(
success: json['status'],
message: json['message'],
data: fromJsonT(json['data']),
);
}
}



import 'dart:convert';

import 'package:demo/api_response.dart';

ApiResponse<T> parseJson<T>(String jsonString, Function fromJsonT) {
try{
final jsonData = json.decode(jsonString);
return ApiResponse.fromJson(jsonData, fromJsonT);
}on FormatException catch (e) {
return ApiResponse(success: false, message: "Invalid JSON format: $e");
}
catch(e){
return ApiResponse(success: false, message: "Error parsing data: $e");
}
}



Comments