6
votes

Sérialisation JSON Flutter - Ne génère pas de fichiers * .g.dart

Je suis nouveau dans le flutter et l'objectif est de sérialiser des objets JSON complexes qui contiennent d'autres objets plus petits.

L'utilisation de json_serializable: ^2.0.0 et du fichier pubspec.yaml ressemble à ceci.

targets:
  $default:
    builders:
      built_value_generator|built_value:
        generate_for:
          - model/*.dart
      json_serializable|json_serializable:
        generate_for:
          - model/*.dart

Le user.dart ressemble à ceci

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable(nullable: false)
class User {
  final String firstName;
  final String lastName;
  final DateTime dateOfBirth;
  User({this.firstName, this.lastName, this.dateOfBirth});
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

J'ai essayé la flutter pub run build_runner build mais le fichier user.g.dart n'est pas créé et je suis confronté à un problème avec cela.

J'ai également ajouté le fichier build.yaml avec le code suivant

dependencies:
  intl: ^0.15.7
  json_annotation: ^2.0.0
  built_value: ^6.7.1
  flutter:
    sdk: flutter

dev_dependencies:
  build_runner: ^1.0.0
  json_serializable: ^2.0.0
  built_value_generator: ^6.7.1
  flutter_test:
    sdk: flutter

Quelqu'un peut-il me dire ce qui me manque ici. Merci


0 commentaires

4 Réponses :


6
votes

L'argument du constructeur ne doit pas être facultatif

part 'User.g.dart';

Ils devraient être obligatoires:

'user.g.dart';

Et la partie

User(this.firstName, this.lastName, this.dateOfBirth);

doit correspondre à la classe Uppercase User:

User({this.firstName, this.lastName, this.dateOfBirth});


4 commentaires

J'ai essayé d'avoir des arguments optionnels et cela a très bien fonctionné. Joyeux flottement.


l'argument obligatoire est correct mais les majuscules ne fonctionnent pas vraiment. Mais les arguments.


Merci, le constructeur d'argument optionnel semblait être le problème pour moi.


Si vous avez une classe comme LoggedUser dans un fichier nommé Logged_user.dart, utilisez la part 'logged_user.g.dart'



0
votes

Le nom du fichier, la classe et la part 'Book.g.dart'; devrait tous correspondre.


1 commentaires

Votre commentaire sur la réponse de Jalil suggérait que cela fonctionnait avec un constructeur d'arguments optionnel. Une chance que vous puissiez insérer le code dans cette réponse? Le passage de l'option aux arguments obligatoires est la seule chose qui a permis à cela de fonctionner pour moi.



0
votes

J'ai eu cette erreur suivante

Erreur

[WARNING] json_serializable:json_serializable on lib/day10/models/sentence.dart:
Missing "part 'sentence.g.dart';".

J'ai remarqué que je devais changer sur le fichier modèle cette part 'Sentence.g.dart'; à cette part 'sentence.g.dart'; en d'autres termes, je devais le mettre en minuscules.


0 commentaires

4
votes

Liste de contrôle
  • vos fichiers de classe sont sous / lib ou / bin
    • peut être des sous-répertoires sous ceux
    • json_serializable ne recherchera pas dans tous les répertoires les fichiers à générer.
  • importation ajoutée pour json_annotation:
    • import 'package:json_annotation/json_annotation.dart';
  • vous avez ajouté une directive de part après import instructions d' import
    • votre part fichier est nommé d' après votre nom de fichier de classe ( et non la classe elle - même nom), avec un g ajouté
    • par exemple pour la classe CacheItem avec ...
    • nom de fichier de la classe cache-item.dart ...
    • part 'cache-item.g.dart'; obtient la directive part correspondante.
    • la directive part n'est pas nommée d'après votre classe réelle, mais le nom du fichier de classe.
  • vous avez ajouté @JsonSerializable() au-dessus du nom de la classe
  • vous avez créé un constructeur par défaut pour votre classe.
    • Il peut être vide, avoir des paramètres nommés facultatifs ou des paramètres de position.
    • Tant que vos champs de classe sont accessibles (via le constructeur ou les setters & getters publics), json_serializable peut le gérer. (c'est-à-dire ne pas avoir seulement des propriétés _private et un constructeur vide)
  • vous avez écrit les méthodes stub:
    • factory <Class>.fromJson(json) => _$ClassFromJson(json);
    • toJson() => _$ClassToJson(this)
    • les méthodes stub sont privées (commencez par _ underscore)
    • Les méthodes $ tub ont le $
    • les méthodes stub ont un CaSe approprié (ie Pascal Case )
    • stub factory fournit (Map<String,dynamic> json) comme argument
    • stub toJson() renvoie Map<String,dynamic>

Lorsque tout cela est terminé, essayez d'exécuter le générateur à partir du répertoire racine du projet ...

Dans Flutter:

flutter pub run build_runner build

En pur Dart:

pub run build_runner build

Erreurs courantes

Bad state: Unexpected diagnostics:

Voir cette sortie lors de l'exécution de build_runner est probablement un problème avec flutter et json_annotation selon une version incompatible de l' analyzer . Cela se produit avec les versions de json_serializable antérieures à 3.5 nécessitant un dependency_override de l'analyseur à 0.39.14 ou 0.39.17.

Votre premier pas devrait être d'essayer la dernière version de json_serilizable de pub.dev qui n'a apparemment pas ce problème de dépendance .

Si vous ne pouvez pas mettre à niveau json_serializable, vous pouvez essayer de placer les lignes de remplacement sous dev_dependences :

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'cache-item.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

CacheItem _$CacheItemFromJson(Map<String, dynamic> json) {
  return CacheItem(
    response: json['response'] as String,
  )
    ..created = json['created'] as int
    ..keywords = json['keywords'] as String;
}

Map<String, dynamic> _$CacheItemToJson(CacheItem instance) => <String, dynamic>{
      'created': instance.created,
      'keywords': instance.keywords,
      'response': instance.response,
    };

Remarques

Sous-classe / classe parent

Si votre classe est un enfant d'une classe parent et que vous souhaitez sérialiser les champs / propriétés de l'enfant uniquement, vous ne pouvez annoter que la sous-classe . Les champs de classe parente seront automatiquement trouvés et inclus dans les fichiers de classe générés pour la sous-classe.

Si vous voulez pouvoir sérialiser / désérialiser le parent et l'enfant séparément , continuez et @JsonSerializable également les classes de base / parent avec @JsonSerializable .

par exemple, nom de fichier account.dart

import 'package:json_annotation/json_annotation.dart';

part 'cache-item.g.dart';

@JsonSerializable()
class CacheItem {
  int created;
  String keywords;
  String response;

  CacheItem({this.response});

  factory CacheItem.fromJson(Map<String,dynamic> json) => _$CacheItemFromJson(json);
  Map<String,dynamic> toJson() => _$CacheItemToJson(this);
}

Produit:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'cache-item.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

CacheItem _$CacheItemFromJson(Map<String, dynamic> json) {
  return CacheItem(
    json['created'] as int,
    json['keywords'] as String,
    json['response'] as String,
  );
}

Map<String, dynamic> _$CacheItemToJson(CacheItem instance) => <String, dynamic>{
      'created': instance.created,
      'keywords': instance.keywords,
      'response': instance.response,
    };

Références et documents

Exemple

import 'package:json_annotation/json_annotation.dart';

part 'cache-item.g.dart';

@JsonSerializable()
class CacheItem {
  int created;
  String keywords;
  String response;

  CacheItem(this.created, this.keywords, this.response);

  factory CacheItem.fromJson(Map<String,dynamic> json) => _$CacheItemFromJson(json);
  Map<String,dynamic> toJson() => _$CacheItemToJson(this);
}

Production

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'account.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Account _$AccountFromJson(Map<String, dynamic> json) {
  return Account()
    ..created = json['created'] as int
    ..username = json['username'] as String
    ..password = json['password'] as String
    ..id = json['id'] as int;
}

Map<String, dynamic> _$AccountToJson(Account instance) => <String, dynamic>{
      'created': instance.created,
      'username': instance.username,
      'password': instance.password,
      'id': instance.id,
    };

Exemple de variante de constructeur

Cet exemple est le même que ci-dessus sauf que le constructeur manque certains champs et a une response facultative.

C'est bon.

Le générateur utilisera simplement les setters publics (implicites) après avoir instancié l'objet pour affecter les valeurs.

import 'package:json_annotation/json_annotation.dart';

part 'account.g.dart';

class AccountBase {
  int created;
  String username;
  String password;
}

@JsonSerializable()
class Account extends AccountBase {
  int id;

  Account();

  factory Account.fromJson(Map<String,dynamic> json) => _$AccountFromJson(json);
  Map<String,dynamic> toJson() => _$AccountToJson(this);
}

Production

dev_dependencies:
  build_runner: ^1.9.0
  flutter_test:
    sdk: flutter
  json_serializable: 3.3.0
  test: ^1.14.3

dependency_overrides:
  analyzer: '0.39.14'

3 commentaires

Celui-ci était vraiment utile, le plus important est de ne pas utiliser de dépendances supplémentaires, utilisez simplement ce qui est suggéré par @Baker. +1


J'ai tout vérifié et je confirme que je ne génère pas la méthode de conversion model-json


MEILLEURE RÉPONSE JAMAIS!