13

I have the following two classes where one is extending from the other like this :

@JsonSerializable(nullable: true)
class Response {
  final String responseCode;
  final String responseMessage;
  final String errorLog;
  Response({this.errorLog, this.responseCode, this.responseMessage});
  factory Response.fromJson(Map<String, dynamic> json) =>
      _$ResponseFromJson(json);
}

.........................................................

 @JsonSerializable(nullable: false)
class Verify extends Response {
  Data data;
  Verify({
    this.data,
  });
  factory Verify.fromJson(Map<String, dynamic> json) => _$VerifyFromJson(json);
  Map<String, dynamic> toJson() => _$VerifyToJson(this);
}

and whenever I'm trying to read response class properties from Verify class, it's always null.

so please how to achieve this?

Chetan Goyal
  • 435
  • 5
  • 14
Baraa Aljabban
  • 992
  • 13
  • 22
  • [tag:datacontractjsonserializer] *is a .NET component that makes it possible to directly serialize .NET objects into JSON data*. Since you are using flutter and dart and not c# or any other .Net language, I removed the tag. – dbc Jun 02 '20 at 13:58

4 Answers4

14

this one I have solved by passing the parameters to super in verify class constructor like this

@JsonSerializable()
class VerifyResponse extends Response {
  Data data;

  VerifyResponse({
    this.data,
    String responseCode,
    String responseMessage,
  }) : super(responseCode: responseCode, responseMessage: responseMessage);

  factory VerifyResponse.fromJson(Map<String, dynamic> json) =>
      _$VerifyResponseFromJson(json);

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

and for the response class it remains the same

@JsonSerializable()
class Response {
  final String responseCode;
  final String responseMessage;

  Response({this.responseCode, this.responseMessage});

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

it's a bit annoying but it's what it's.

Baraa Aljabban
  • 992
  • 13
  • 22
2

You should remove 'final' keyword from Response Class

@JsonSerializable(nullable: true)
    class Response {
      String responseCode;
      String responseMessage;
      String errorLog;
      Response({this.errorLog, this.responseCode, this.responseMessage});
      factory Response.fromJson(Map<String, dynamic> json) =>
           _$ResponseFromJson(json);
}
mfv
  • 171
  • 1
  • 1
  • 8
0

It worked by adding super(); explicitly to the child class's constructor.

@JsonSerializable()
class VerifyResponse extends Response {
  Data data;

  VerifyResponse({
    this.data,
    String responseCode,
    String responseMessage,
    //No need to list all parent class properties
    }) : super();

  factory VerifyResponse.fromJson(Map<String, dynamic> json) =>
      _$VerifyResponseFromJson(json);

  Map<String, dynamic> toJson() => _$VerifyResponseToJson(this);
}
Omar Fayad
  • 1,733
  • 3
  • 11
  • 27
0

I would like to extend the answer as there are a couple more gotchas.

You can't use the super.responseCode syntax in the constructor:

Incorrect

  VerifyResponse({
    this.data,
    super.responseCode,
    super.responseMessage,
  })

Correct

  VerifyResponse({
    this.data,
    String responseCode,
    String responseMessage,
  }) : super(responseCode: responseCode, responseMessage: responseMessage);

You also have to define the type in the constructor, otherwise they get passed to the super constructor as dynamic:

Incorrect

  VerifyResponse({
    required this.data,
    required responseCode,
    required responseMessage,
  }) : super(responseCode: responseCode, responseMessage: responseMessage);

Correct

  VerifyResponse({
    required this.data,
    required String responseCode,
    required String responseMessage,
  }) : super(responseCode: responseCode, responseMessage: responseMessage);
c.lamont.dev
  • 693
  • 1
  • 6
  • 14