google / json_serializable.dart

Generates utilities to aid in serializing to/from JSON.
https://pub.dev/packages/json_serializable
BSD 3-Clause "New" or "Revised" License
1.55k stars 397 forks source link

List<Object> serialization error #680

Closed no1seman closed 4 years ago

no1seman commented 4 years ago

Hi,

after updating flutter & packages got the following problem: code:

...
@freezed
abstract class NoteDto with _$NoteDto {
  NoteDto._();

  factory NoteDto({
    @JsonKey(ignore: true) String id,
    @required String body,
    @required int color,
    **@required List<TodoItemDto> todos,**
    @required @ServerTimestampConverter() FieldValue serverTimeStamp,
  }) = _NoteDto;

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

@freezed
abstract class TodoItemDto with _$TodoItemDto {  
  const TodoItemDto._();
  const factory TodoItemDto({
    @required String id,
    @required String name,
    @required bool done,
  }) = _TodoItemDto;

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

Result:

...

Map<String, dynamic> _$_$_NoteDtoToJson(_$_NoteDto instance) =>
    <String, dynamic>{
      'body': instance.body,
      'color': instance.color,
      **'todos': instance.todos,**
      'serverTimeStamp':
          const ServerTimestampConverter().toJson(instance.serverTimeStamp),
    };
...

Expected result:

Map<String, dynamic> _$_$_NoteDtoToJson(_$_NoteDto instance) =>
    <String, dynamic>{
      'body': instance.body,
      'color': instance.color,
      **'todos': instance.todos?.map((e) => e?.toJson())?.toList(),**
      'serverTimeStamp':
          const ServerTimestampConverter().toJson(instance.serverTimeStamp),
    };
flutter doctor -v [√] Flutter (Channel beta, 1.20.0-7.3.pre, on Microsoft Windows [Version 10.0.18363.959], locale ru-RU) • Flutter version 1.20.0-7.3.pre at c:\Dev\flutter • Framework revision e606910f28 (5 days ago), 2020-07-28 16:06:37 -0700 • Engine revision ac95267aef • Dart version 2.9.0 (build 2.9.0-21.10.beta) [√] Android toolchain - develop for Android devices (Android SDK version 29.0.3) • Android SDK at c:\Users\user\AppData\Local\Android\Sdk • Platform android-29, build-tools 29.0.3 • ANDROID_HOME = c:\Users\user\AppData\Local\Android\Sdk • ANDROID_SDK_ROOT = c:\Users\user\AppData\Local\Android\Sdk • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) • All Android licenses accepted. [√] Chrome - develop for the web • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe [√] Android Studio (version 4.0) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin version 48.0.2 • Dart plugin version 193.7361 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) [√] VS Code (version 1.47.3) • VS Code at C:\Users\user\AppData\Local\Programs\Microsoft VS Code • Flutter extension version 3.13.1 [√] Connected device (3 available) • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 84.0.4147.105 • Edge (web) • edge • web-javascript • Microsoft Edge 84.0.522.52 • No issues found!
pubspec.yaml environment: sdk: ">=2.8.0 <3.0.0" dependencies: flutter: sdk: flutter flushbar: 1.10.4 injectable: 1.0.2 get_it: 4.0.4 dartz: 0.9.1 freezed_annotation: 0.11.0+1 hydrated_bloc: 6.0.0 flutter_bloc: 6.0.1 firebase_core: 0.4.5 firebase_auth: 0.16.1 google_sign_in: 4.5.1 cloud_firestore: 0.13.7 uuid: 2.2.0 auto_route: 0.6.7 kt_dart: 0.7.0+1 json_annotation: 3.0.1 rxdart: 0.24.1 flutter_slidable: 0.5.5 flutter_hooks: 0.12.0 dwds: 5.1.0 reorderables: 0.3.2 provider: 4.3.1 implicitly_animated_reorderable_list: 0.2.3 hydrated_bloc_storage: path: packages/hydrated_bloc_storage dev_dependencies: build_runner: 1.10.1 freezed: 0.11.4 lint: 1.2.0 injectable_generator: 1.0.3 auto_route_generator: 0.6.7 json_serializable: 3.3.0 flutter_test: sdk: flutter

pubspec.lock: pubspec.zip

jmrboosties commented 4 years ago

https://flutter.dev/docs/development/data-and-backend/json

Specifically:

All looks fine now, but if you do a print() on the user object:

Address address = Address("My st.", "New York");
User user = User("John", address);
print(user.toJson());

The result is:

{name: John, address: Instance of 'address'}

When what you probably want is output like the following:

{name: John, address: {street: My st., city: New York}}

To make this work, pass explicitToJson: true in the @JsonSerializable() annotation over the class declaration. The User class now looks as follows:

import 'address.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';

@JsonSerializable(explicitToJson: true)
class User {
  String firstName;
  Address address;

  User(this.firstName, this.address);

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}
no1seman commented 4 years ago

@jmrboosties thanks for the answer, it's a breaking change in new versions of freezed, so as for now it's needed to add annotation not for all class but it's constructor: ` @freezed abstract class NoteDto with $NoteDto { NoteDto.();

@JsonSerializable(explicitToJson: true) // <- need to be added here with new versions of freezed factory NoteDto({ @JsonKey(ignore: true) String id, @required String body, @required int color, @required List todos, @required @ServerTimestampConverter() FieldValue serverTimeStamp, }) = _NoteDto;

factory NoteDto.fromJson(Map<String, dynamic> json) => _$NoteDtoFromJson(json); ... } ` Thanks a lot! Closing this issue.