Reputation: 1559
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?
Upvotes: 13
Views: 7314
Reputation: 692
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>{},
});
}
Upvotes: 3
Reputation: 7799
You need to cast T
as BaseResponse
:
data = (T as BaseResponse).fromJson(json['data']);
Upvotes: 0