简体   繁体   中英

How to create objects of generic types in flutter/dart?

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": "a@b.com",
        "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?

ok let's add a little hack to manage your use case:

  • let say that you have two responses 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) {}
} 
  • the trick is that you will decide the type of BaseResponse at ApiResponse constructor like this
class 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');
    }
  }
}
  • both responses will work
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>{},
  });
}
 

您需要将TBaseResponse

data = (T as BaseResponse).fromJson(json['data']);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM