100 % local: tus datos nunca salen de tu navegador

JSON a Dart — fromJson y toJson ya escritos

Convierte una muestra JSON en clases de Dart. Las claves originales viven en los fromJson y toJson generados: el mapeo es código que se lee y se depura.

Instantáneo Privado Cero cookies

Entrada JSON

Salida Dart

Qué hace esta herramienta

Una muestra JSON pasa a ser clases de Dart, cada una con una fábrica fromJson y un método toJson.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
class Root {
  final int id;
  final String firstName;
  final Address address;

  Root({required this.id, required this.firstName, required this.address});

  factory Root.fromJson(Map<String, dynamic> json) => Root(
        id: json['id'] as int,
        firstName: json['firstName'] as String,
        address: Address.fromJson(json['address'] as Map<String, dynamic>),
      );

  Map<String, dynamic> toJson() => <String, dynamic>{
        'id': id,
        'firstName': firstName,
        'address': address.toJson(),
      };
}

Sin build_runner, sin anotaciones, sin archivo part generado: la correspondencia está ahí, a la vista, y puedes cambiarla.

La clave nunca se va

Un nombre de campo de Dart no lleva guion ni empieza por dígito, y class está reservado. Cuando un nombre debe cambiar, ambos sentidos conservan la clave:

  final String contentType;
  final int class_;

  factory Root.fromJson(Map<String, dynamic> json) => Root(
        contentType: json['content-type'] as String,
        class_: json['class'] as int,
      );

  Map<String, dynamic> toJson() => <String, dynamic>{
        'content-type': contentType,
        'class': class_,
      };

Como la correspondencia es código y no una convención, nada se adivina en ejecución, y lees lo que se enviará antes de enviarlo.

Listas y objetos anidados

Una lista de objetos pasa a ser una clase aparte, y la correspondencia la recorre:

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

Una lista de escalares usa cast, más barato: (json['tags'] as List<dynamic>).cast<String>().

Lo que una muestra no puede decir

Cada campo es final y required, y ninguno admite nulos, porque el documento traía un valor para cada uno. Una clave ausente se vuelve así un TypeError al decodificar, que nombra el campo, en vez de un null que viaja tres pantallas antes de romper.

Solo un null da dynamic, que acepta todo y no comprueba nada. Una lista vacía o mezclada da List<dynamic> por la misma razón. Son los tres sitios que conviene revisar en cuanto tengas una segunda carga.

Privado por diseño

Todo se ejecuta localmente en tu navegador con JavaScript. Tus datos nunca se suben a un servidor, lo que hace que la herramienta sea segura para contenido sensible y funcione sin conexión.

Preguntas frecuentes

¿Hace falta json_serializable o build_runner?
No. La fábrica `fromJson` y el método `toJson` se escriben enteros: la clase funciona con `jsonDecode` y nada más. Si tu proyecto ya usa json_serializable, su código generado hace el mismo trabajo con anotaciones; esta salida es la versión que puedes leer sin lanzar un build.
¿Qué pasa si falta una clave en ejecución?
El cast lanza. `json['id'] as int` sobre una clave ausente es un `null` casteado a `int`, o sea un `TypeError` que nombra el campo. Es el fallo ruidoso, y es el bueno: una muestra donde la clave siempre estaba no puede decirte que es opcional. Pasa el campo a `int?` y quita el `required` cuando lo sepas.
¿Puedo desactivar los métodos JSON?
Sí: el ajuste deja la clase con sus campos y su constructor. Viene bien cuando pegas en una base que genera la serialización en otro sitio, o cuando la clase es un simple portador de valores que nunca se cruza con JSON.

Convertidores relacionados