Json_serializable.dart: Documentation for using the new @JsonSerializable(genericArgumentFactories: true) (3.5.0)

Created on 23 Sep 2020  路  2Comments  路  Source: google/json_serializable.dart

I am trying to take advantage of the new genericArgumentFactories in 3.5.0 version but can't figure out how to call the fromJson function.

Here is what i tried:
ApiResponse.fromJson(json.decode(apiData.body), NameDto.fromJson)

But this gives me the error:
The getter 'fromJson' isn't defined for the type 'NameDto'.

Is there an example/documentation on how to call these new function? If not could one be added please. I have searched but did not find any.

Classes and dependencies i use:

import 'package:json_annotation/json_annotation.dart';

part 'ApiResponse.g.dart';

@JsonSerializable(genericArgumentFactories: true)
class ApiResponse<T> {
  ApiResponse(this.successful, this.errorCode, this.errorMessage, this.data);

  @JsonKey(name: 'Successful')
  final bool successful;
  @JsonKey(name: 'ErrorCode')
  final String errorCode;
  @JsonKey(name: 'ErrorMessage')
  final String errorMessage;
  @JsonKey(name: 'Data')
  final T data;

  factory ApiResponse.fromJson(Map<String, dynamic> json, T Function(Object json) fromJsonT) => _$ApiResponseFromJson(json, fromJsonT);
  Map<String, dynamic> toJson(Object Function(T value) toJsonT) => _$ApiResponseToJson(this, toJsonT);
}
@JsonSerializable()
class NameDto {
  NameDto (this.firstName, this.lastName);

  final String firstName;
  final String lastName;

  factory NameDto.fromJson(Map<String, dynamic> json) => _$NameDtoFromJson(json);
  Map<String, dynamic> toJson() => _$NameDto ToJson(this);
}
dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.3
  json_annotation: ^3.0.0
  http: ^0.12.2
  analyzer: 0.39.14
  flutter_simple_dependency_injection: any

dev_dependencies:
  flutter_test:
    sdk: flutter

  json_serializable: ^3.5.0
  build_runner: ^1.0.0

Most helpful comment

The trick here: the fromJson factory is not a function, per se. So you have to wrap it.

This works for me:

import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';

part 'api_response.g.dart';

@JsonSerializable(genericArgumentFactories: true)
class ApiResponse<T> {
  ApiResponse(this.successful, this.errorCode, this.errorMessage, this.data);

  @JsonKey(name: 'Successful')
  final bool successful;
  @JsonKey(name: 'ErrorCode')
  final String errorCode;
  @JsonKey(name: 'ErrorMessage')
  final String errorMessage;
  @JsonKey(name: 'Data')
  final T data;

  factory ApiResponse.fromJson(
          Map<String, dynamic> json, T Function(Object json) fromJsonT) =>
      _$ApiResponseFromJson(json, fromJsonT);

  Map<String, dynamic> toJson(Object Function(T value) toJsonT) =>
      _$ApiResponseToJson(this, toJsonT);
}

@JsonSerializable()
class NameDto {
  NameDto(this.firstName, this.lastName);

  final String firstName;
  final String lastName;

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

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

void main() {
  const data = r'''
{
   "Data": {}
}
''';

  print(
    ApiResponse.fromJson(
      jsonDecode(data) as Map<String, dynamic>,
      (j) => NameDto.fromJson(j as Map<String, dynamic>),
    ),
  );
}

All 2 comments

The trick here: the fromJson factory is not a function, per se. So you have to wrap it.

This works for me:

import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';

part 'api_response.g.dart';

@JsonSerializable(genericArgumentFactories: true)
class ApiResponse<T> {
  ApiResponse(this.successful, this.errorCode, this.errorMessage, this.data);

  @JsonKey(name: 'Successful')
  final bool successful;
  @JsonKey(name: 'ErrorCode')
  final String errorCode;
  @JsonKey(name: 'ErrorMessage')
  final String errorMessage;
  @JsonKey(name: 'Data')
  final T data;

  factory ApiResponse.fromJson(
          Map<String, dynamic> json, T Function(Object json) fromJsonT) =>
      _$ApiResponseFromJson(json, fromJsonT);

  Map<String, dynamic> toJson(Object Function(T value) toJsonT) =>
      _$ApiResponseToJson(this, toJsonT);
}

@JsonSerializable()
class NameDto {
  NameDto(this.firstName, this.lastName);

  final String firstName;
  final String lastName;

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

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

void main() {
  const data = r'''
{
   "Data": {}
}
''';

  print(
    ApiResponse.fromJson(
      jsonDecode(data) as Map<String, dynamic>,
      (j) => NameDto.fromJson(j as Map<String, dynamic>),
    ),
  );
}

The trick here: the fromJson factory is not a function, per se. So you have to wrap it.

This works for me:

import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';

part 'api_response.g.dart';

@JsonSerializable(genericArgumentFactories: true)
class ApiResponse<T> {
  ApiResponse(this.successful, this.errorCode, this.errorMessage, this.data);

  @JsonKey(name: 'Successful')
  final bool successful;
  @JsonKey(name: 'ErrorCode')
  final String errorCode;
  @JsonKey(name: 'ErrorMessage')
  final String errorMessage;
  @JsonKey(name: 'Data')
  final T data;

  factory ApiResponse.fromJson(
          Map<String, dynamic> json, T Function(Object json) fromJsonT) =>
      _$ApiResponseFromJson(json, fromJsonT);

  Map<String, dynamic> toJson(Object Function(T value) toJsonT) =>
      _$ApiResponseToJson(this, toJsonT);
}

@JsonSerializable()
class NameDto {
  NameDto(this.firstName, this.lastName);

  final String firstName;
  final String lastName;

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

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

void main() {
  const data = r'''
{
   "Data": {}
}
''';

  print(
    ApiResponse.fromJson(
      jsonDecode(data) as Map<String, dynamic>,
      (j) => NameDto.fromJson(j as Map<String, dynamic>),
    ),
  );
}

But should be another way to do it, is so invasive to do that... To many libraries expect that fromJson only have's one parameter as argument, and this will require two.
馃槹

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xiang23 picture xiang23  路  5Comments

AlexBigCheese picture AlexBigCheese  路  3Comments

vipinagrahari picture vipinagrahari  路  5Comments

fzyzcjy picture fzyzcjy  路  5Comments

HosseinArabbeigi picture HosseinArabbeigi  路  3Comments