VIBHOR GOYAL
VIBHOR GOYAL

Reputation: 503

Flutter deserialisation using generics error

I am trying to deserialise and serialise a generic class in flutter using build_runner. The code I have written is as below:

import 'package:json_annotation/json_annotation.dart';
import 'api_response_message_model.dart';

part 'api_response_base_model.g.dart';

@JsonSerializable()
class ApiResponseBaseModel<T> {
  @JsonKey(fromJson: _dataFromJson, toJson: _dataToJson)
  T data;
  ApiResponseMessageModel message;

  ApiResponseBaseModel({this.data, this.message});

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

  T _dataFromJson<T>(Map<String, dynamic> input) =>
      input['value'] as T;

  Map<String, dynamic> _dataToJson<T>(T input) =>
      {'value': input};
}

I am getting the error as below when running command flutter packages pub run build_runner build --delete-conflicting-outputs

Could not generate `fromJson` code for `data`.
None of the provided `TypeHelper` instances support the defined type.
package:premier_app/models/api_response_base_model.dart:10:5
  ╷
10│   T data;
  │     ^^^^
  ╵

Please help me identify the problem and know the correct solution.

I also did tried the method mentioned here but no luck in removing the error - https://github.com/dart-lang/json_serializable/blob/7b40e9b04805bf921e4cebb87ec4ad7b8e1a2d29/json_serializable/test/generic_files/generic_class.dart#L20-L21

Upvotes: 1

Views: 1918

Answers (1)

Hemanth Raj
Hemanth Raj

Reputation: 34819

Please move the _dataFromJson & _dataToJson methods outside the scope of class ApiResponseBaseModel<T>.

Example:

import 'package:json_annotation/json_annotation.dart';
import 'api_response_message_model.dart';

part 'api_response_base_model.g.dart';

@JsonSerializable()
class ApiResponseBaseModel<T> {
  @JsonKey(fromJson: _dataFromJson, toJson: _dataToJson)
  T data;
  ApiResponseMessageModel message;

  ApiResponseBaseModel({this.data, this.message});

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

T _dataFromJson<T>(Map<String, dynamic> input) =>
    input['value'] as T;

Map<String, dynamic> _dataToJson<T>(T input) =>
    {'value': input};

I did try out myself, works! Generated methods look like:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'api_response_base_model.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

ApiResponseBaseModel<T> _$ApiResponseBaseModelFromJson<T>(
    Map<String, dynamic> json) {
  return ApiResponseBaseModel<T>(
    data: _dataFromJson(json['data'] as Map<String, dynamic>),
    message: json['message'],
  );
}

Map<String, dynamic> _$ApiResponseBaseModelToJson<T>(
        ApiResponseBaseModel<T> instance) =>
    <String, dynamic>{
      'data': _dataToJson(instance.data),
      'message': instance.message,
    };

Upvotes: 3

Related Questions