1

I am using Flutter with json_annotation library and have one data class that is used to represent json response coming from one api.

import 'package:json_annotation/json_annotation.dart';
import 'package:app/dtos/user.dart';
import 'package:app/dtos/limited_user.dart';


part 'pending_project.g.dart';

@JsonSerializable()
class PendingProject {
  @JsonKey(name: "user")
  final User|LimitedUser user; // here I might have sometimes returned User type other types LimitedUser

  @JsonKey(name: "updatedAt")
  final String updatedAt;

  PendingProject(this.user, this.updatedAt);

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

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

The api returns different values for user field based on some logic. Sometimes objects of type User other types of type LimitedUser

I have both those objects defined but cannot make it work in the json schema above.

How can I leave user object as dynamic maybe or json string and further parse manually in code or some other solution

Both User and LimitedUser have one common field named type that allows us to differentiate what we got back.

for User, type="user"

for LimitedUser, type="limitedUser"

all the other fields can be different we cannot assume anything else

PS: pending_project.g.dart is auto generated file with the library itself by running flutter packages pub run build_runner build

Kristi Jorgji
  • 1,154
  • 1
  • 14
  • 39
  • How do you know which class it is when you get the json? Do those two have a relationship (does one extend the other) or are they completely separate entities? – nvoigt May 12 '22 at 11:26
  • Let us assume those are completely separate entities. Can I leave the `user` field as json string and parse manually in code (the code knows what to expects based on user roles). Also I can tell by checking if a specific field "type" exists inside the object. `if type==="user" or type ==="limitedUser"` that is why I am wondering if can have some dynamic mapper of sort and "union type" – Kristi Jorgji May 12 '22 at 11:27

1 Answers1

2

I solved this by using fromJson as below

@JsonKey(name: "user", fromJson: mapUser)
final Object user;


/// other code

Object mapUser(Map<String, dynamic> value)  {
  if (value['type'] == 'user') {
    User.fromJson(value);
  }

  return LimitedUser.fromJson(value);
}

The other code in ui is checking:

if (obj is User) {
  return somewidgetforuser(obj);
}
return somewidgedforlimiteduser(obj);
Kristi Jorgji
  • 1,154
  • 1
  • 14
  • 39