Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
895 views
in Technique[技术] by (71.8m points)

parsing - Flutter - How to parsed nested json to a class with generics?

I'm wondering how can I parse a nested json to a class with generic types. My intention is to wrap responses from the backend (like loginRespose that contains a token) with a code and a message

I have

class BaseResponse<T>{
  int code;
  String message;
  T responseObject;

  BaseResponse.fromJson(Map<String, dynamic> parsedJson)
    : code = parsedJson['Code'],
      message = parsedJson['Message'],
      responseObject = T.fromJson(parsedJson['ResponseObject']); //This is what I'd like to do
}

Obviously the last line throws an error because T doesn't has a named constructor "fromJson". I tried adding some restrictions to the Type but I didn't find any solutions. Do you have any idea on how to pull this off?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can't do such thing, at least not in flutter. As dart:mirror is disabled and there's no interface for classes constructors.

You'll have to take a different route.

I'll recommend using POO instead. You would here give up on deserializing responseObject from your BaseResponse. And then have subclass of BaseResponse handles this deserialization

Typically you'd have one subclass per type:

class IntResponse extends BaseResponse<int> {
  IntResponse.fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    this.responseObject = int.parse(json["Hello"]);
  }
}

You can then hide this mess away by adding a custom factory constructor on BaseResponse to make it more convenient to use.

class BaseResponse<T> {
  int code;
  String message;
  T responseObject;

  BaseResponse._fromJson(Map<String, dynamic> parsedJson)
      : code = parsedJson['Code'],
        message = parsedJson['Message'];

  factory BaseResponse.fromJson(Map<String, dynamic> json) {
    if (T == int) {
      return IntResponse.fromJson(json) as BaseResponse<T>;
    }
    throw UnimplementedError();
  }
}

Then either instantiate the wanted type directly, or use the factory constructor :

final BaseResponse foo = BaseResponse.fromJson<int>({"Hello": "42", "Code": 42, "Message": "World"});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...