ОБНОВЛЕНИЕ Я создал небольшой пример и добавлю весь код в этот пост. Я должен верить, что есть ответ / объяснение этому, и я надеюсь, что кто-то может рассказать мне о том, что я скучаю. Поля классов, которые являются объектами типа, не конвертируются, и я не понимаю, почему.
Вот классы моделей, с которыми я работаю.
import 'package:json_annotation/json_annotation.dart';
part 'parent.g.dart';
@JsonSerializable()
class Parent {
int id;
final String name;
final int age;
List<Child> children;
Job job;
Parent({this.name, this.age, this.children, this.job});
factory Parent.fromJson(Map<String, dynamic> json) => _$ParentFromJson(json);
Map<String, dynamic> toJson() => _$ParentToJson(this);
}
@JsonSerializable()
class Child{
int id;
final String name;
final int age;
Child({this.name, this.age});
factory Child.fromJson(Map<String, dynamic> json) => _$ChildFromJson(json);
Map<String, dynamic> toJson() => _$ChildToJson(this);
}
@JsonSerializable()
class Job{
int id;
String title;
Job({this.title});
factory Job.fromJson(Map<String, dynamic> json) => _$JobFromJson(json);
Map<String, dynamic> toJson() => _$JobToJson(this);
}
Вот сгенерированный файл .g для этих классов
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'parent.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Parent _$ParentFromJson(Map<String, dynamic> json) {
return Parent(
name: json['name'] as String,
age: json['age'] as int,
children: (json['children'] as List)
?.map(
(e) => e == null ? null : Child.fromJson(e as Map<String, dynamic>))
?.toList(),
job: json['job'] == null
? null
: Job.fromJson(json['job'] as Map<String, dynamic>),
)..id = json['id'] as int;
}
Map<String, dynamic> _$ParentToJson(Parent instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'age': instance.age,
'children': instance.children,
'job': instance.job,
};
Child _$ChildFromJson(Map<String, dynamic> json) {
return Child(
name: json['name'] as String,
age: json['age'] as int,
)..id = json['id'] as int;
}
Map<String, dynamic> _$ChildToJson(Child instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'age': instance.age,
};
Job _$JobFromJson(Map<String, dynamic> json) {
return Job(
title: json['title'] as String,
)..id = json['id'] as int;
}
Map<String, dynamic> _$JobToJson(Job instance) => <String, dynamic>{
'id': instance.id,
'title': instance.title,
};
Вот класс DAO для родительского класса
import 'package:sembast/sembast.dart';
import 'package:json_serial_test/services/app_database.dart';
import 'package:json_serial_test/models/parent.dart';
class ParentDao {
static const String PARENT_STORE_NAME = 'parents';
// A Store with int keys and Map<String, dynamic> values.
// This Store acts like a persistent map, values of which are Parent objects converted to Map
final _parentStore = intMapStoreFactory.store(PARENT_STORE_NAME);
// Private getter to shorten the amount of code needed to get the
// singleton instance of an opened database.
Future<Database> get _db async => await AppDatabase.instance.database;
Future insert(Parent parent) async {
await _parentStore.add(await _db, parent.toJson());
}
Future update(Parent parent) async {
// For filtering by key (ID), RegEx, greater than, and many other criteria,
// we use a Finder.
final finder = Finder(filter: Filter.byKey(parent.id));
await _parentStore.update(
await _db,
parent.toJson(),
finder: finder,
);
}
Future deleteAll() async {
await _parentStore.delete(await _db);
}
Future delete(Parent parent) async {
final finder = Finder(filter: Filter.byKey(parent.id));
await _parentStore.delete(
await _db,
finder: finder,
);
}
Future<List<Parent>> getAllSortedByName() async {
// Finder object can also sort data.
final finder = Finder(sortOrders: [
SortOrder('name'),
]);
final recordSnapshots = await _parentStore.find(
await _db,
finder: finder,
);
// Making a List<Parent> out of List<RecordSnapshot>
return recordSnapshots.map((snapshot) {
final parent = Parent.fromJson(snapshot.value);
// An ID is a key of a record from the database.
parent.id = snapshot.key;
return parent;
}).toList();
}
}
Вот мой тест
// Setup
final k1 = Child(name: 'Billy', age: 10);
final k2 = Child(name: 'Jannet', age: 9);
final job = Job(title: 'Cook');
final List<Child> kids = [k1, k2];
final dad = Parent(name: 'Dave', age: 52, job: job, children: kids);
await pDao.insert(dad);
List<Parent> dadsInDb = await pDao.getAllSortedByName();
print('Dads from DB: ${dadsInDb.toString()}');
При попытке вставить Parent в мою базу данных Sembast, это ошибка, которая появляется.
E/flutter (12986): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Invalid argument(s): value Instance of 'Child' unsupported type Child E/flutter (12986): #0 cloneValue (package:sembast/src/utils.dart:191:3) E/flutter (12986): #1 cloneValue.<anonymous closure> (package:sembast/src/utils.dart:177:33) E/flutter (12986): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:29) E/flutter (12986): #3 ListIterable.toList (dart:_internal/iterable.dart:221:19) E/flutter (12986): #4 cloneValue (package:sembast/src/utils.dart:177:52) E/flutter (12986): #5 cloneValue.<anonymous closure> (package:sembast/src/utils.dart:174:49) E/flutter (12986): #6 MapMixin.map (dart:collection/maps.dart:165:28) E/flutter (12986): #7 cloneValue (package:sembast/src/utils.dart:173:18) E/flutter (12986):
#8 SembastStore.txnPutSync (package:sembast/src/store_impl.dart:133:15) E/flutter (12986): #9 SembastStore.txnAdd (package:sembast/src/store_impl.dart:117:11) E/flutter (12986): <asynchronous suspension> E/flutter (12986): #10 StoreRefMixin.add.<anonymous closure> (package:sembast/src/store_ref_impl.dart:75:12) E/flutter (12986): #11 SembastDatabase.inTransaction.<anonymous closure> (package:sembast/src/database_impl.dart:1238:34) E/flutter (12986):
#12 SembastDatabase.transaction.<anonymous closure>.<anonymous closure> (package:sembast/src/database_impl.dart:1090:59) E/flutter (12986): #13 new Future.sync (dart:async/future.dart:224:31) E/flutter (12986): #14 SembastDatabase.transaction.<anonymous closure> (package:sembast/src/database_impl.dart:1090:26) E/flutter (12986): #15 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:32:26) E/flutter (12986):
#16 SembastDatabase.transaction (package:sembast/src/database_impl.dart:1073:38) E/flutter (12986):
#17 SembastDatabase.inTransaction (package:sembast/src/database_impl.dart:1238:7) E/flutter (12986): #18 StoreRefMixin.add (package:sembast/src/store_ref_impl.dart:72:25) E/flutter (12986): #19 ParentDao.insert (package:json_serial_test/data/parent_dao.dart:17:24) E/flutter (12986): <asynchronous suspension> E/flutter (12986): #20
_MyHomePageState.build.<anonymous closure> (package:json_serial_test/main.dart:120:22) E/flutter (12986): #21
_InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14) E/flutter (12986):
#22 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36) E/flutter (12986):
#23 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) E/flutter (12986): #24 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11) E/flutter (12986): #25 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5) E/flutter (12986): #26 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:236:7) E/flutter (12986): #27 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27) E/flutter (12986):
#28 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:222:20) E/flutter (12986):
#29 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) E/flutter (12986):
#30 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) E/flutter (12986):
#31 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) E/flutter (12986):
#32 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) E/flutter (12986):
#33 _rootRunUnary (dart:async/zone.dart:1138:13) E/flutter (12986): #34 _CustomZone.runUnary (dart:async/zone.dart:1031:19) E/flutter (12986): #35 _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7) E/flutter (12986): #36 _invoke1 (dart:ui/hooks.dart:273:10) E/flutter (12986): #37
_dispatchPointerDataPacket (dart:ui/hooks.dart:182:5) E/flutter (12986):
Если кто-то могли бы помочь мне показать, что я пропустил, сделал неправильно, я был бы очень признателен.
ОРИГИНАЛЬНЫЙ ПОЧТА ============ == Должен ли json_serializable
преобразовать ВЕСЬ класс в JSON, или есть ли ограничения, на которые я нахожусь?
Я решил попытаться решить множество проблем, которые я сам вызвал, с помощью json_serializable
для создания методов to Json и Json, необходимых для работы с NoSQL DB
.
Если я создаю класс, который включает в себя поле List<Ojb>
, сгенерированный код, по-видимому, приводит к JSON для каждого поля класса, но не может сделать это для объектов в списке.
Простой пример
class Parent {
final int age;
final String name;
List<Child> children;
Parent({this.age, this.name, this.children});
}
class Child {
final int age;
final String name;
Child({this.age, this.name});
}
Когда я использую json_serializable, который, кажется, прекрасно работает, я получаю методы Json и Json для вышеупомянутых классов. На первый взгляд все выглядит идеально.
Когда я пытаюсь вставить Parent (содержащий дочерние элементы) в мою базу данных No SQL, вставка не может сказать, что тип (ссылающийся на дочерний объект) не поддерживается - Верное утверждение, с этим проблем не возникает.
Когда я прохожу через это через отладчик, вот что я вижу.
Parent
преобразуется в возраст карты, отображаемый в качестве ключа с его значением имя отображается как ключ с его значением
До этого момента я вижу, что все является картой [.. и все выглядит великолепно
Затем мы попадаем в список Дочерних объектов.
Эта часть не преобразуется в карту, но все еще существует в виде списка дочерних объектов, что означает сбой вставки.
Оба класса имеют аннотацию jsonSerializable
Оба классы генерируют ожидаемый код (часть), классы
Все работает отлично, пока я не пытаюсь использовать List<myObject>
в одном из моих классов.
Вся причина можно было бы использовать пакет вроде json_serializable полагается на код, который автоматически генерируется, и не должен создавать его сам. Я не хочу вручную обновлять автоматически сгенерированный код, чтобы решить эту проблему, поэтому я не вставил код. Если это ответ, то я пойду другим путем.
Мой вопрос: есть ли какая-то конфигурация, которую я пропускаю или, возможно, делаю неправильно, что позволило бы ВСЕМ элементам в классе быть преобразованным в map / json, даже если поля класса не просто простые типы int и string. Я ожидаю, что у меня может быть класс, который включает в себя примитивы, наряду с объектами, списки объектов и т. Д. c. и все должно генерироваться правильно или нет?