2

I'm working on the ApiResponse class of my Flutter project and this class needs a T data attribut.
I want to use JsonSerializable to generate the fromJson() method but this error appears when I tried to :

ListResponse<T> _$ListResponseFromJson<T extends JsonSerializable>(Map<String, dynamic> json, T Function(Object?) fromJsonT)

I defined the those two files :

1. Base response

part "base_response.g.dart";

@JsonSerializable()
abstract class BaseResponse {
  dynamic message;
  bool success;

  BaseResponse({this.message, required this.success});

  factory BaseResponse.fromJson(Map<String, dynamic> json) =>
      _$BaseResponseFromJson(json);
}

2. List response

part "list_response.g.dart";

@JsonSerializable(genericArgumentFactories: true)
class ListResponse<T extends JsonSerializable> extends BaseResponse {
  List<T> data;

  ListResponse({
    required String super.message,
    required super.success,
    required this.data,
  });

  factory ListResponse.fromJson(Map<String, dynamic> json) =>
      _$ListResponseFromJson(json, WHAT SHOULD BE HERE ?);
}

So my problem now is that JsonSerializable need another parameter in ListResponseFromJson() :

How to dynamically pass the T.fromJson() to _$ListResponseFromJson(json, ???) ?

YannMLD
  • 21
  • 2
  • `static` methods are not part of a class's interface. There is no way to guarantee that `T` has a `static` `fromJson` method. You instead must make `ListResponse.fromJson` take a `fromJson` callback that it can pass along. Whatever calls `ListResponse.fromJson` should be responsible for supplying a `fromJson` callback appropriate for that `T`. – jamesdlin Mar 08 '23 at 07:31

1 Answers1

0

You can use generic function that takes Object? and returns T, and then pass it to _$ListResponseFromJson method:

@JsonSerializable(genericArgumentFactories: true)
class ListResponse<T extends JsonSerializable> extends BaseResponse {
  List<T> data;

  ListResponse({
    required String message,
    required bool success,
    required this.data,
  }) : super(message: message, success: success);

  factory ListResponse.fromJson(
      Map<String, dynamic> json, T Function(Object? json) fromJsonT) {
    return _$ListResponseFromJson(json, fromJsonT);
  }

  static T _fromJson<T extends JsonSerializable>(
      Object? json, T Function(Object? json) fromJsonT) {
    return fromJsonT(json);
  }

  Map<String, dynamic> toJson() => _$ListResponseToJson(this);

  factory ListResponse.fromList(List<T> list,
      {String message = '', bool success = true}) {
    return ListResponse(
        message: message, success: success, data: List<T>.from(list));
  }

  factory ListResponse.empty({String message = '', bool success = true}) {
    return ListResponse(message: message, success: success, data: []);
  }
}
angwrk
  • 394
  • 1
  • 8