Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems generating classes when complexe object in constructor #1234

Closed
chrisDK1977 opened this issue Oct 27, 2022 · 4 comments
Closed

Problems generating classes when complexe object in constructor #1234

chrisDK1977 opened this issue Oct 27, 2022 · 4 comments

Comments

@chrisDK1977
Copy link

chrisDK1977 commented Oct 27, 2022

As I got no answer on that on stackoverflow I hope for an answer here.

When extending a class and serializing a complexe object I get some problems. Ist seems the problem only existing when extending and having the complexe object in the constructor:

import 'package:json_annotation/json_annotation.dart';
part 'app_user.g.dart';

@JsonSerializable(explicitToJson: true)
class AppUser extends BaseUser{
  String name;


  AppUser(this.name, avatar) : super(avatar);

  factory AppUser.fromJson(Map<String, dynamic> json) => _$AppUserFromJson(json);
  Map<String, dynamic> toJson() => _$AppUserToJson(this);
}

class BaseUser{
  AvatarConfiguration? avatar;

  BaseUser(AvatarConfiguration avatar);
}

@JsonSerializable()
class AvatarConfiguration{
  @JsonKey(name: "he")
  int head;
  @JsonKey(name: "ha")
  int hair;
  @JsonKey(name: "no")
  int nose;
  @JsonKey(name: "mo")
  int mouth;
  @JsonKey(name: "ey")
  int eye;


  AvatarConfiguration(this.head, this.hair, this.nose, this.mouth, this.eye);

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

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

}

I get that generated:

part of 'app_user.dart';

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

AppUser _$AppUserFromJson(Map<String, dynamic> json) => AppUser(
      json['name'] as String,
      json['avatar'],
    );

Map<String, dynamic> _$AppUserToJson(AppUser instance) => <String, dynamic>{
      'avatar': instance.avatar?.toJson(),
      'name': instance.name,
    };

AvatarConfiguration _$AvatarConfigurationFromJson(Map<String, dynamic> json) =>
    AvatarConfiguration(
      json['he'] as int,
      json['ha'] as int,
      json['no'] as int,
      json['mo'] as int,
      json['ey'] as int,
    );

Map<String, dynamic> _$AvatarConfigurationToJson(
        AvatarConfiguration instance) =>
    <String, dynamic>{
      'he': instance.head,
      'ha': instance.hair,
      'no': instance.nose,
      'mo': instance.mouth,
      'ey': instance.eye,
    };


and

json['avatar'],

is not what I expect.

When not extending the class

@JsonSerializable(explicitToJson: true)
class AppUser{
  String name;
  AvatarConfiguration? avatar;

  AppUser(this.name, this.avatar);

  factory AppUser.fromJson(Map<String, dynamic> json) => _$AppUserFromJson(json);
  Map<String, dynamic> toJson() => _$AppUserToJson(this);
}

I get what I expect:

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

AppUser _$AppUserFromJson(Map<String, dynamic> json) => AppUser(
      json['name'] as String,
      json['avatar'] == null
          ? null
          : AvatarConfiguration.fromJson(
              json['avatar'] as Map<String, dynamic>),
    );

Map<String, dynamic> _$AppUserToJson(AppUser instance) => <String, dynamic>{
      'name': instance.name,
      'avatar': instance.avatar?.toJson(),
    };
...

Can anyone tell me if that is a bug or does it make sense how json_serializable is working???

Version is 6.5.3

[√] Flutter (Channel stable, 3.3.5, on Microsoft Windows [Version 10.0.19044.2130], locale de-DE)
• Flutter version 3.3.5 on channel stable at C:\SDKs\flutter_latest\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision d9111f6402 (8 days ago), 2022-10-19 12:27:13 -0700
• Engine revision 3ad69d7be3
• Dart version 2.18.2
• DevTools version 2.15.0

...

@kevmoo
Copy link
Collaborator

kevmoo commented Dec 21, 2022

What is Avatar? It needs to have a fromJson and toJson on it. Or it's just treated like an opaque object.

@github-actions
Copy link

github-actions bot commented Jan 5, 2023

Without additional information we're not able to resolve this issue, so it will be closed at this time. You're still free to add more info and respond to any questions above, though. We'll reopen the case if you do. Thanks for your contribution!

@github-actions github-actions bot closed this as completed Jan 5, 2023
@chrisDK1977
Copy link
Author

chrisDK1977 commented Jan 5, 2023

@kevmoo
Avatar is of Type AvatarConfiguration which has the required methods posted in the question

AvatarConfiguration _$AvatarConfigurationFromJson(Map<String, dynamic> json) =>
    AvatarConfiguration(
      json['he'] as int,
      json['ha'] as int,
      json['no'] as int,
      json['mo'] as int,
      json['ey'] as int,
    );

Map<String, dynamic> _$AvatarConfigurationToJson(
        AvatarConfiguration instance) =>
    <String, dynamic>{
      'he': instance.head,
      'ha': instance.hair,
      'no': instance.nose,
      'mo': instance.mouth,
      'ey': instance.eye,
    };

@kevmoo
Copy link
Collaborator

kevmoo commented Feb 13, 2023

I just put this code

@JsonSerializable(explicitToJson: true)
class AppUser extends BaseUser {
  String name;

  AppUser(this.name, super.avatar);

  factory AppUser.fromJson(Map<String, dynamic> json) =>
      _$AppUserFromJson(json);
  Map<String, dynamic> toJson() => _$AppUserToJson(this);
}

class BaseUser {
  AvatarConfiguration? avatar;

  BaseUser(this.avatar);
}

@JsonSerializable()
class AvatarConfiguration {
  @JsonKey(name: 'he')
  int head;
  @JsonKey(name: 'ha')
  int hair;
  @JsonKey(name: 'no')
  int nose;
  @JsonKey(name: 'mo')
  int mouth;
  @JsonKey(name: 'ey')
  int eye;

  AvatarConfiguration(this.head, this.hair, this.nose, this.mouth, this.eye);

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

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

Got this generated

AppUser _$AppUserFromJson(Map<String, dynamic> json) => AppUser(
      json['name'] as String,
      json['avatar'] == null
          ? null
          : AvatarConfiguration.fromJson(
              json['avatar'] as Map<String, dynamic>),
    );

Map<String, dynamic> _$AppUserToJson(AppUser instance) => <String, dynamic>{
      'avatar': instance.avatar?.toJson(),
      'name': instance.name,
    };

AvatarConfiguration _$AvatarConfigurationFromJson(Map<String, dynamic> json) =>
    AvatarConfiguration(
      json['he'] as int,
      json['ha'] as int,
      json['no'] as int,
      json['mo'] as int,
      json['ey'] as int,
    );

Map<String, dynamic> _$AvatarConfigurationToJson(
        AvatarConfiguration instance) =>
    <String, dynamic>{
      'he': instance.head,
      'ha': instance.hair,
      'no': instance.nose,
      'mo': instance.mouth,
      'ey': instance.eye,
    };

Maybe you need to add in the type in the argument passed to the base type?

@kevmoo kevmoo closed this as completed Feb 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants