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

final fields are not written during serialization #891

Open
MatrixDev opened this issue May 12, 2021 · 5 comments
Open

final fields are not written during serialization #891

MatrixDev opened this issue May 12, 2021 · 5 comments

Comments

@MatrixDev
Copy link

Source code

@JsonSerializable
class MyClass {
  @JsonKey(name: 'value1')
  var value1 = '';

  @JsonKey(name: 'value2')
  final value2 = 'must always be this';
}

Generated code:

MyClass _$MyClassFromJson(Map<String, dynamic> json) {
  return MyClass()..value1 = json['value1'] as String;
}

Map<String, dynamic> _$MyClassToJson(MyClass instance) => <String, dynamic>{
      'value1': instance.value1,
    };

Actual result

vars are written, finals are not

Expected result

all fields must be written - vars and finals

Versions

Flutter 2.0.6
json_annotation: ^4.0.0
json_serializable: ^4.1.0
@kevmoo
Copy link
Collaborator

kevmoo commented May 14, 2021

This is by design. We only "round-trip" values that can be provided when we create the value.

You can always wrap the generated value and add in the final value.

See #274

@kevmoo kevmoo closed this as completed May 14, 2021
@MatrixDev
Copy link
Author

@kevmoo is there any reasoning for this? it is very strange that explicitly saying that I want to serialize something does nothing. At very least codegen should throw an error if this is the case. Explicit stuff cannot be simply ignored, it took me some time to find why API calls where not working because of this.

@esDotDev
Copy link

esDotDev commented Jun 9, 2021

This is bizarre... we have a type, we need to write it into our payload so the server knows what class this is.

I don't understand the rationale.

class Address {
  final String street;

  const Address({
    this.street = '',
    this.street2 = '',
    this.city = '',
    this.state = '',
    this.postalCode = '',
    this.country = '',
  });

  final String type= "Address"; // We need this in the payload... why is this not a valid use case?
}

This is the elegant approach, not being able to do this leads to a can of worms... we can't be const anymore, which causes all kinds of issues with Dart and constructors, or we violate seperation of concerns and have a bunch of hacky hard to maintain code that injects types into payloads, which gets even harder with nesting, for example serializing Customer(address: Address()) where Address needs a key injected... big hassle.

Why not at least give us JsonKey(include: true) or an option to includeFinal for the project as a whole?

@kevmoo
Copy link
Collaborator

kevmoo commented Jun 10, 2021

I'll reopen this issue. PR's are welcome!

@sgehrman
Copy link

This sounds crazy. Are you saying this won't work:

I haven't tried json_serializable yet, I'm looking for a replacement for simple_json (which is the best, but not being updated)

I can't have finals?

class AnnotationModel {
AnnotationModel({
required this.containerId,
required this.content,
required this.createdAt,
required this.id,
required this.modifiedAt,
required this.status,
});

final String containerId;
final String content;
final DateTime createdAt;
final String id;
final DateTime modifiedAt;
final String status;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants