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

Transforming empty nested map to object exception #1388

Open burekas7 opened 9 months ago

burekas7 commented 9 months ago

Following to this issue: https://stackoverflow.com/questions/75522984/transforming-empty-nested-map-to-object-exception

I have the same problem. But this problem happens only when I run a unit tests. When I use the parse the same json in my app (Get the same json as dio response) it's ok, But when I use the same json as mock value for unit tests, it throws an exception since there is object value {}

What is the best way to handle cases of empty objects? Why does it happen only in the unit tests when I use the json object as mock value.

(When e value is {}, not null)

Location.fromJson(e as Map<String, dynamic>))

It comes from this: (When json['locations'] value is [{}], not null) From the generated file. The problem is with the Location.fromJson

      locations: (json['locations'] as List<dynamic>?)
          ?.map((e) => Location.fromJson(e as Map<String, dynamic>))
          .toList(),

The main problem is with e as Map<String, dynamic> that behaves differently.

Unhandled exception:
type '_Map<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast

Thank you in advance.

burekas7 commented 9 months ago

I see there is a manual solution like this: But how can I set this option for all my models using JsonSerializable, instead of doing it one by one?

import 'package:json_annotation/json_annotation.dart';

part 'my_data.g.dart';

@JsonSerializable()
class MyData {
  @JsonKey(fromJson: _fromJson, toJson: _toJson)
  Map<String, dynamic>? key;

  MyData({this.key});

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

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

  static Map<String, dynamic>? _fromJson(Map<String, dynamic>? json) {
    // Check if json is an empty object and return null
    return json != null && json.isEmpty ? null : json;
  }

  static Map<String, dynamic>? _toJson(Map<String, dynamic>? json) {
    // Check if json is an empty object and return null
    return json != null && json.isEmpty ? null : json;
  }
}