Dart json serializable - decode value as different type

Viewed 41

Let's say I'm building an app that receives a json as a response, for example:

{
  "a": 5,
  "b": [1, 2, 3]
}

Let's say I want to parse this json into the following class:

class Example {
  String a;
  List<String> b;
}

Using Dart's json_serializable package I can do the following

String intToString(int value) => value.toString();
List<String> intToStringList(List<int> value) => value.map(intToString).toList();

@JsonSerializable()
class Example {
  @JsonKey(fromJson: intToString)
  String a;
  @JsonKey(fromJson: intToStringList)
  List<String> b;

  Example(this.a, this.b);

  factory Example.fromJson(Map<String, dynamic> json) => _$ExampleFromJson(json);
  Map<String, dynamic> toJson() => _$ExampleToJson(this);
}

My question is if there is any built in, more elegant way to do this without custom method implementations.

1 Answers

I do not think that the problem is in the implementation of the generator. I tried another generator and there is also no other way.

import 'dart:io';

import 'package:object_serializer/json_serializer_generator.dart';
import 'package:yaml/yaml.dart';

void main() {
  final classes = loadYaml(_classes) as Map;
  final g = JsonSerializerGenerator();
  final classesCode = g.generateClasses(classes);
  final values = {
    'classes': classesCode,
  };

  var source = g.render(_template, values);
  source = g.format(source);
  File('bin/stackoverflow.dart').writeAsStringSync(source);
}

const _classes = r'''
Example:
  fields:
    a:
      type: String
      deserialize: "(x){ return x == null ? '0' : '$x'; }"
    b:
      type: List<String>
      deserialize: "(x){ return x == null ? <String>[] : (x as List).map((e) => e == null ? '0' : '$x').toList(); }"
''';

const _template = r'''
{{classes}}
''';

The same problem.
Even a little more code is required, as "deserialize" is not post-processing, but a complete implementation of a custom deserialization processing.

class Example {
  Example({required this.a, required this.b});

  factory Example.fromJson(Map json) {
    return Example(
      a: (x) {
        return x == null ? '0' : '$x';
      }(json['a']),
      b: (x) {
        return x == null
            ? <String>[]
            : (x as List).map((e) => e == null ? '0' : '$x').toList();
      }(json['b']),
    );
  }

  final String a;

  final List<String> b;

  static List<Example> fromJsonList(List json) {
    return json.map((e) => Example.fromJson(e as Map)).toList();
  }

  Map<String, dynamic> toJson() {
    return {
      'a': a,
      'b': b,
    };
  }

  static List<Map<String, dynamic>> toJsonList(List<Example> list) {
    return list.map((e) => e.toJson()).toList();
  }
}
Related