How can we create object of generic types in dart?
For my use case, each of my api responses are wrapped as ApiResponse
class. For login api response, I get a json object such as
{
"data": {
"email": "[email protected]",
"name": "A"
},
"message": "Successful",
"status": true
}
So to parse these responses, I created classes as below, but they throw compile time error stating that The method 'fromJson' isn't defined for the class 'Type'. :
class ApiResponse<T extends BaseResponse> {
bool status;
String message;
T data;
ApiResponse.fromJson(Map<String, dynamic> json) {
status = json['status'];
message = json['message'];
data = T.fromJson(json['data']); // <<<------- here is the compile time error
}
}
abstract class BaseResponse {
BaseResponse.fromJson(Map<String, dynamic> json);
}
class Login extends BaseResponse {
String name, email;
Login.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
name = json['name'];
email = json['email'];
}
}
// and I want to use it like below
usage() {
ApiResponse<Login> a = ApiResponse.fromJson({});
String name = a.data.name;
}
Can anyone help me fix the error?
Generic objects are structures for storing and interacting with data in an app. They are the primary type of entity through which the engine provides access to the components of an app.
In Dart, by default collections are heterogeneous. However, by the use of generics, we can make a collection to hold homogeneous values. The use of Generics makes the use of a single compulsory data type to be held inside the collection.
ok let's add a little hack to manage your use case:
Login
and Error
both of Type BaseResponse
abstract class BaseResponse {}
class Login extends BaseResponse {
Login.fromJson(Map<String, dynamic> json) {}
}
class Error extends BaseResponse {
Error.fromJson(Map<String, dynamic> json) {}
}
BaseResponse
at ApiResponse
constructor like thisclass ApiResponse<T extends BaseResponse> {
T data;
ApiResponse.fromJson(Map<String, dynamic> json) {
data = _getProperDataValue<T>(json['data']);
}
static E _getProperDataValue<E extends BaseResponse>(
Map<String, dynamic> jsonData) {
switch (E) {
case Login:
return Login.fromJson(jsonData) as E;
case Error:
return Error.fromJson(jsonData) as E;
default:
throw UnsupportedError('Not Supported Type');
}
}
}
void main(List<String> arguments) {
final loginRes = ApiResponse<Login>.fromJson(<String, dynamic>{
'data': <String, dynamic>{},
});
final errorRes = ApiResponse<Error>.fromJson(<String, dynamic>{
'data': <String, dynamic>{},
});
}
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