Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart, Can't call Generic's method

I am trying to create an abstract data model where i pass data and type a and then is return list, but when i can't call T.fromJson() method, note that passes type has method fromJson()

class DataList<T> {
  final bool success; 
  dynamic data;


  InfosResponse({
    this.success,
    List<dynamic> data,   
  }) {
    castDataToList(data);
  }

  factory DataList.fromJson(Map<String, dynamic> json) {
    return DataList(
      success: json['success'],
      data: json['data'],
    );
  }

  void castDataToList(jsonData) {
    this.data = List<T>.from(jsonData.map((x) => T.fromJson(x)));
  }
}
like image 200
Tornike Kurdadze Avatar asked Nov 19 '18 06:11

Tornike Kurdadze


2 Answers

You cannot call static methods on type variables. Static methods must be known at compile-time, and the value of a type variable is not known until run-time.

You can parameterize your class with the method that you want to call:

class DataList<T> {
  final bool success; 
  dynamic data;
  T Function(Object) fromJson;

  DataList({
    this.success,
    List<dynamic> data,   
    this.fromJson;
  }) : data = castDataToList(data);

  factory DataList.fromJson(Map<String, dynamic> json, T fromJson(Object o)) {
    return DataList(
        success: json['success'],
        data: json['data'],
        fromJson: fromJson,
    );
  }

  List<T> castDataToList(jsonData) =>
      [for (var x in jsonData) fromJson(x)];
}

When you want to use the class with a type, Foo which has a fromJson static method or constructor, you create the instance as:

var dataList = DataList<Foo>.fromJson(someJsonMap, Foo.fromJson);

This passes the Foo.fromJson function to the class, which can then use it when needed.

like image 155
lrn Avatar answered Nov 17 '22 01:11

lrn


to use Irn answer with constructors try passing them like this

(Map<String, dynamic> json) => Foo.fromJson(Map<String, dynamic> json);
like image 28
Tariq Avatar answered Nov 17 '22 02:11

Tariq