Coder Social home page Coder Social logo

k-paxian / dart-json-mapper Goto Github PK

View Code? Open in Web Editor NEW
399.0 6.0 33.0 2.07 MB

Serialize / Deserialize Dart Objects to / from JSON

Home Page: https://pub.dev/packages/dart_json_mapper

License: Other

Dart 100.00%
flutter dart json serialization deserialization dartlang dart-json-mapper reflection tojson fromjson

dart-json-mapper's People

Contributors

herrniklasraab avatar ipcjs avatar k-paxian avatar kennelken avatar norbert515 avatar schultek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dart-json-mapper's Issues

Can`t use JsonMapper in production build for web platform

Given this code

import 'package:dart_json_mapper/json_mapper.dart';
import 'package:dart_json_mapper/annotations.dart';

import 'main.reflectable.dart';

@jsonSerializable
class TridaA {
  TridaA() {
    print("TridaA constructed");
  }
  String prop;
}

void main() async {
  // inicializace reflektoru
  initializeReflectable();

  print(".main");
  jsonSerializable.annotatedClasses.forEach((cls) {
    print("Annotated class ${cls.qualifiedName}");
  });

  print("allClasses ${jsonSerializable.annotatedClasses}");
  var mirror = jsonSerializable.annotatedClasses.firstWhere((cm) {
    print("   class ${cm.simpleName} ~ ${cm.reflectedType.toString()}");
    return cm.simpleName == "TridaA";
  });

  print("Instance by reflection: ${mirror.newInstance("", [], {})}");

  var map = Map<String, dynamic>.from({"b": Map<String, dynamic>.from({"prop": "test"})});

  var instance = JsonMapper.instance
    .deserializeObject(map, TridaA);

  print("Instance by JsonMapper: ${instance}");

}

Everything is OK if it is built with dartdevc, but when compiled with dart2js by:
webdev serve web:43751 --hot-reload --release
with minification, it raise error:

Uncaught It seems your class 'minified:a6' has not been annotated with @jsonSerializable
at Object.c (localhost:43751/main.dart.js:2719:3)
at bX.a2 (localhost:43751/main.dart.js:5437:20)
at bX.bB (localhost:43751/main.dart.js:5442:30)
at localhost:43751/main.dart.js:6122:49
at ef.a (localhost:43751/main.dart.js:3678:72)
at ef.$2 (localhost:43751/main.dart.js:3804:23)
at Object.jI (localhost:43751/main.dart.js:3659:3)
at Object.fD (localhost:43751/main.dart.js:6124:10)
at localhost:43751/main.dart.js:6532:8
at localhost:43751/main.dart.js:6527:55

Integration with mobx

I'm trying to use this excellent library along with dart mobx. Unfortunately I believe that it does not support the self-generated code with mobx_codegen ...
For example the simple following class obviously works perfectly:

@jsonSerializable
class TestChain {
  List<String> mailingList = List<String>();
}

main()
{
  initializeReflectable();
  var test = TestChain();
  test.mailingList.add("[email protected]");
  test.mailingList.add("[email protected]");
  test.mailingList.add("[email protected]");
  var a = JsonMapper.serialize(test); 
  print(a);
  var ab= JsonMapper.deserialize<TestChain>(a);
  print(ab);
}

If I modify the class so that I can use mobx (even if I don't insert any observable)

@jsonSerializable
class TestChain extends _TestChain with _$TestChain {

}

@jsonSerializable
abstract class _TestChain with Store{
  List<String> mailingList = List<String>();
}

I get the following error at runtime

Exception has occurred.
_TypeError (type 'List<dynamic>' is not a subtype of type 'List<String>' of 'value')

Any suggestions?

How to register List of List

Hello,

Thank you again for the great package.

I have a list of list coming from API as in the following picture.

image

I couldn't register the type. I get the following error.

E/flutter (30766): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>'
E/flutter (30766): #0      JsonMapper.deserializeObject (package:dart_json_mapper/src/mapper.dart:475:21)
E/flutter (30766): #1      JsonMapper.deserializeObject.<anonymous closure> (package:dart_json_mapper/src/mapper.dart:478:26)
E/flutter (30766): #2      MappedListIterable.elementAt (dart:_internal/iterable.dart:417:29)

How can I register a list of lists of objects?

Global Settings

Hello,

is there a way to for example to set ignoreNullMembersto true for the whole project? Or was it a design decision to don't have a global configuration?

Best,

Niklas

Featurerequest: Typenamehandling

Sorry for coming up here again :). But...

I am also in a situation where I need to handle something like this:

@jsonSerializable
class Business {
  String name;
}

@jsonSerializable
class Hotel extends Business {
  int stars;
  Hotel(this.stars);
}

@jsonSerializable
class Startup extends Business {
  int userCount;

  Startup(this.userCount);
}

@jsonSerializable
class Stakeholder {
  String fullName;
  List<Business> businesses;

  Stakeholder(this.fullName, this.businesses);
}

main() {
  var jack = Stakeholder("Jack", <Business>[Startup(10), Hotel(4)]);
  var json = JsonMapper.serialize(jack);
  var jack2 = JsonMapper.deserialize<Stakeholder>(json);
  jack2.businesses[0] is Startup; //Should be true
  jack2.businesses[1] is Hotel; //Should be true
}

The serializer should be able to, get the current type, save it in a JSON property, for example, "$type". And can create those types based on the "$type" property.

Newtonsoft.NET is handling this very pretty: https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm

Because you are using a kind of "reflection", and not this complicated code generation JSON stuff, this should be possible right?

If you need any help, I am willing to do, but I've never contributed to an open source project, so you are dealing with a noob :).

Thanks and a happy day,

Niklas

Serialize and Deserialize from and to Map<String, dynamic>

Hey @k-paxian,

as I started developing my base class repository for Firestore, another issue came up. The type of document data in the Firestore for Flutter package is always of type Map<String, dynamic>. Because Firestore is the go-to for Flutter and Angular developer, additional serialization and deserialization methods who can handle a Map<String, dynamic> type, would be a huge benefit. I would suggest the following signature:

static Map<String, dynamic> JsonMapper.serializeToMap(Object model);
static T JsonMapper.deserializeFromMap<T>(Map<String, dynamic> map);

Here is a simplified example of how I would use this in my repository:

class Repository<TModel extends DataModel> {
  CollectionReference collectionReference;

  Repository(this.collectionReference);

  Future update(TModel model) async {
    Map<String, dynamic> map = JsonMapper.serializeToMap(model);
    await collectionReference.document(model.id).updateData(map);
  }

  Future<TModel> get(String id) async {
    var snapshot = await collectionReference.document(id).get();
    return JsonMapper.deserializeFromMap<TModel>(snapshot.data)..id = id;
  }
}

What do you think about this?

Niklas

Error while using this with Flutter Firestore

I'm using this library to deserialize Firestore documents, and I'm seeing the following error whenever I try to call JsonMapper.fromMap<T>(data);

E/flutter (23945): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type '_ImmutableMap<dynamic, dynamic>' is not a subtype of type 'Map<String, String>'
E/flutter (23945): null
E/flutter (23945): [ERROR:flutter/shell/common/shell.cc(199)] Dart Error: Unhandled exception:
E/flutter (23945): type '_ImmutableMap<dynamic, dynamic>' is not a subtype of type 'Map<String, String>'
E/flutter (23945): #0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:1114:29)
E/flutter (23945): #1      _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
E/flutter (23945): #2      _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)

I was seeing a similar issue with json_serializable, but I was able to fix it with an option they provided in my build.yaml: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/anyMap.html

Issue with Generic type ?

Hi,

I run into an issue :

image

Unsupported operation: Attempt to obtain reflectedType from generic class .EasivioModel.

This append also to a non-abstract class.

import 'dart:convert';

import 'package:dart_json_mapper/dart_json_mapper.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

@immutable
@jsonSerializable
@Json(typeNameProperty: 'technicalName', ignoreNullMembers: true)
abstract class EasivioModel<T> extends Equatable {
  final String parentUuid;
  final String uuid;

  const EasivioModel({this.parentUuid, this.uuid});

  @override
  List<Object> get props => [
        parentUuid,
        uuid,
      ];

  @override
  bool get stringify => true;

  T copyWith();

  T merge(T other);

  T fromJson(Map<String, dynamic> jsonData) {
    return JsonMapper.deserialize<T>(json.encode(jsonData));
  }

  Map<String, dynamic> toJson() {
    return json.decode(JsonMapper.serialize(this));
  }
}

Commenting the @jsonSerializable resolve the issue but I need it to comply with :
First thing you should do is to put @jsonSerializable annotation on each of those classes
=> It seems your class 'EasivioModel<dynamic>' has not been annotated with @jsonSerializable

Something I do wrong ?

Does this work for "private" fields?

Hello Alexander,

at first, I am so grateful, that someone developed a JSON mapper, without this awful boilerplate code. Those mixins and abstract just for serialization is a step back and by far no innovation. So thank you!

So to my problem:
I have a lot of classes like the one below. The problem is, those are my business objects, so I need a serializer, who can also serialize private fields. As I looked in the source code of dart-json-mapper this feature seems not to exist right now. Of course, I only want to use the serializer in the same library. Otherwise, we wouldn't have access to them.

Would be great to have this, because this is a dealbreaker for me, and should be easy to set up. At least as an option.

class User extends Model implements IImmutableUser {
  String _email;

  String get email => _email; // Here happens, more business stuff in general.
  set email(String email) => _email = email; // Here happens, more business stuff in general.
}

Hopefully we find a solution on this :).

Thanks,

Niklas

A few Questions

Hello @k-paxian,

https://codingpassion.net just joined as Encouragement Sponsor! We love the sponsorware approach. This decision was made because we want to commit longterm to this framework. And we will have a lot of questions and requirements in the future. So thank you for that!

A few questions/requirements that came up while developing:

  • Is there any way to get support for enums in Lists? For example List<Color>()
  • Would it be possible to specify @Json(typeNameProperty: 'typeName') in SerializationOptions() globally?
  • Would it be possible to have an option in SerializationOptions(), that would serialize/deserialize only properties marked with @JsonProperty() and ignores all unmarked?
  • Waiting for #38 (HashSet, UnmodifiableListView, UnmodifiableMapView are needed)
  • Do sponsors get features marked with "sponsorware" immediately or earlier?

Thanks,

Niklas

Wrong targeted data when parsing

Hi,
I have a special case:

@jsonSerializable
class A {
  @JsonProperty(name: "content")
  B content;
}

@jsonSerializable
class B {
  @JsonProperty(name: "content")
  List<A> content;
}

When I parse a json like:

{
      "content": {
           "content": []
      }
}

I expect to have A as a root object. But there is an error that it use B's content as A's content.
After debugging, I've realized that here is the problem:

dynamic getPropertyValue(String name) {
    dynamic result;
    _isPathExists(_getPath(name), (m, k) {
      result = (m is Map && m.containsKey(k)) ? m[k] : m;
    });
    return result;
  }

To fix it, should it only be:

result = m;

? (Because m[k] is B's content).

Thank you

Can't convert List<Car>

// Deserialize
print(JsonMapper.deserialize<Person>(personJson));

print to:

Unhandled exception:
type List<dynamic> is not a subtype of type List<Car> of 'value'
#0      _data.<anonymous closure> (file:///E:/Flutter/dart-json-mapper-master/example/example.reflectable.dart:519:61)
#1      _InstanceMirrorImpl.invokeSetter (package:reflectable/src/reflectable_builder_based.dart:346:20)
#2      JsonMapper.deserializeObject.<anonymous closure> (package:dart_json_mapper/json_mapper.dart:523:12)
#3      JsonMapper.enumeratePublicFields (package:dart_json_mapper/json_mapper.dart:296:14)
#4      JsonMapper.deserializeObject (package:dart_json_mapper/json_mapper.dart:502:5)
#5      JsonMapper.deserialize (package:dart_json_mapper/json_mapper.dart:59:21)
#6      main (file:///E:/Flutter/dart-json-mapper-master/example/example.dart:101:20)
#7      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#8      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

Ability to have “partial” deserialization from JSON

In many cases input JSON has many fields, which are not needed for particular UI. So I’m declaring class with let’s say 5 fields out of 20 in JSON. Currently I’m getting error on attempt to deserialize from JSON in such situations, so I have to carefully declare all fields in my classes to be fully consistent with input JSON, which is boring and useless in many cases.

Api can either return string or object for same field

Hello !

I'm trying to setup dart-json-mapper with a ld+json api.

API side of serialization could return a string or an object for any relation in my model. See examples below :

{
  iri: "/packaging_details/1",
  packaging: "/packagings/1",
  name: "bag"
}
{
  iri: "/packaging_details/1",
  packaging: {iri: "/packagings/1", weight: 10},
  name: "bag"
}

When I have a string, it ends with the following error :

Unhandled Exception: It seems your Enum class field is missing annotation:
@JsonProperty(enumValues: Packaging.values)

I think I should do a converter but I don't really understand how to implement it. Also, should I make a converter for each model or it's possible to make a "universal" one ?

Thank you

Enum and Equatable incompatibility

Hi,

Run into this issue an issue with equatable today.

The following code :

import 'package:dart_json_mapper/dart_json_mapper.dart';
import 'package:equatable/equatable.dart';

enum MyColor { black, red }

@jsonSerializable
@Json(ignoreNullMembers: true)
class MyCarModel extends Equatable {
  final String model;

  @JsonProperty(enumValues: MyColor.values)
  final MyColor color;

  const MyCarModel({this.model, this.color});

  @override
  List<Object> get props => [model, color];

  Map<String, dynamic> toJson() {
    return JsonMapper.toMap(this);
  }
}

Will trigger this exception :

--¶ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ¶----------------------------------------------------
The following _MissingEnumValuesErrorImpl was thrown running a test:
It seems your Enum class field is missing annotation:
@JsonProperty(enumValues: MyColor.values)

When the exception was thrown, this was the stack:
#0      JsonMapper.serializeObject (package:dart_json_mapper/src/mapper.dart:481:9)
#1      JsonMapper.serializeIterable.<anonymous closure> (package:dart_json_mapper/src/mapper.dart:452:32)
#2      MappedListIterable.elementAt (dart:_internal/iterable.dart:417:29)
#3      ListIterable.toList (dart:_internal/iterable.dart:221:19)
#4      JsonMapper.serializeIterable (package:dart_json_mapper/src/mapper.dart:452:64)
#5      JsonMapper.serializeObject.<anonymous closure> (package:dart_json_mapper/src/mapper.dart:529:32)
#6      JsonMapper.enumeratePublicFields (package:dart_json_mapper/src/mapper.dart:329:14)
#7      JsonMapper.serializeObject (package:dart_json_mapper/src/mapper.dart:509:5)
#8      JsonMapper.serialize (package:dart_json_mapper/src/mapper.dart:40:18)
#9      JsonMapper.toMap (package:dart_json_mapper/src/mapper.dart:60:9)
#10     MyCarModel.toJson (package:easivio/domain/models/user_model.dart:168:23)
#11     main.<anonymous closure>.<anonymous closure> (file:///C:/Users/Stephane/easivio/easivio-mobile/test/onboarding_test.dart:47:29)
<asynchronous suspension>
#12     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:124:25)
#13     TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:696:19)
<asynchronous suspension>
#16     TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:679:14)
#17     AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1050:24)
#23     AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1047:15)
#24     testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:121:22)
#25     Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:171:27)
<asynchronous suspension>
#26     Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:242:15)
#31     Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:239:5)
#32     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:169:33)
#37     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:168:13)
#38     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:392:25)
#52     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:384:19)
#53     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:418:5)
#54     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
(elided 28 frames from class _FakeAsync, package dart:async, package dart:async-patch, and package stack_trace)

Regards

The method 'map' was called on null.

Exception has occurred.
NoSuchMethodError (NoSuchMethodError: The method 'map' was called on null.
Receiver: null
Tried calling: map<Object>(Closure: (dynamic) => Object))

I am using :

@jsonSerializable
class UserModel {
  String fullName;
  String password;
  int age = 25;
  int gender = 1;
  bool isActive;
  AccountModel accountBank;
  int id;
  String userName;
  String email;
  String avatar;
  List<ContactModel> contacts;

  UserModel({
    this.fullName,
    this.password,
    this.accountBank,
    this.age,
    this.email,
    this.gender,
    this.id,
    this.userName,
    this.avatar,
    this.isActive,
    this.contacts,
  });
}

and

@jsonSerializable
class ContactModel {
  String value;
  @JsonProperty(name: "contact_type")
  ContactTypeModel contactType;
  UserModel user;
  @JsonProperty(name: "contact_type_id")
  int contactTypeId;
  int id;

  ContactModel({
    this.value,
    this.contactType,
    this.user,
    this.contactTypeId,
    this.id,
  });
}

if I delete List<ContactModel> contacts property , I don't get this issue.
but in my case , I shouldn't delete that.
also in my main :

initializeReflectable();
  JsonMapper().useAdapter(
    JsonMapperAdapter(
      valueDecorators: {
        typeOf<List<ContactModel>>(): (value) => value.cast<ContactModel>()
      },
    ),
  );
  runApp(child: MyApp());

could not generate main.reflectable.dart and need a simple mobx example

Hello,

Thanks for the great library,

I couldn't generate main.reflectable.dart file. I tried to follow the basic setup. I pasted all the additional code in my main.dart file and run the command pub run build_runner build. I get the following error:

'pub' is not recognized as an internal or external command, operable program or batch file.

flutter pub run build_runner build command works but it does not generate main.reflectable.dart file.

Besides, I need a very simple mobx example with a separate store. I am especially interested in very nested json deserialization. This could be used for example json: https://jsonplaceholder.typicode.com/posts

I already starred the repo. Thank you very much in advance.

Any tips on how to use it with multiple model files ?

Hi guys,

It seems to have a bug when trying to use it with the follow structure:

  • lib
    • models
      • model1.dart
      • model2.dart

I've looked at the generated model1.reflectable.dart and model2.reflectable.dart and the initializeReflectable changes the r.data to the new one so I think this is causing the miss behavior.

Any tips on that ? I didnt dig deep to see how the internals are working.

Bug in tests: '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Pt'

Hi!
I got an error with deserializing so i decided test it inside your test themselves.
I added deserializing inside test test/test.constructors.dart:170 in this way:

    String pTargetJson = JsonMapper.serialize(pTarget, '');
    final PtDerived pTargetBack = JsonMapper.deserialize(pTargetJson); // My string

and got an error too
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Pt'

[Question] Compatibility with Freezed ?

All is in the title ;)

Is there a way to define the default serializer to make it compatible with Freezed ?
Since it support decorator, that should be feasible, what do you think ?

Regards

Collect Unmapped Properties

Support alternative for @JsonAnySetter from Java jackson

{
    "firstName": "",
    "lastName": "",
    "extraProp": 1,
    "extraProp2": 2
}

=>

@jsonSerializable
class Object {
   String firstName;
   String lastName;

   @jsonAnySetter
    unmappedProperty(String name, dynamic value) {
       // collect into internal map
    }
}

Is this library may work with inheritance and generics?

Hi!
The fact is i tried to work with

@jsonSerializable
class Base<T> {
  final T value;
  Base(this.value);
}

@jsonSerializable
class Derived extends Base<String>{
  Derived(String value) : super(value);
}

and just simply with

@jsonSerializable
class Base {
  final String value;

  Base(this.value);
}

@jsonSerializable
class Derived extends Base{
  Derived(String value) : super(value);
}

and got the same errors:

NoSuchMethodError: The getter 'reflectedType' was called on null.
  Receiver: null
  Tried calling: reflectedType
  dart:core/runtime/libobject_patch.dart 50:5        Object.noSuchMethod
  package:dart_json_mapper/json_mapper.dart 228:62   JsonMapper.enumeratePublicFields
  package:dart_json_mapper/json_mapper.dart 355:5    JsonMapper.serializeObject
  package:dart_json_mapper/json_mapper.dart 45:37    JsonMapper.serialize
  bin/test/undostacktest.dart 33:22                  main.<fn>
  package:test_api/src/backend/declarer.dart 168:27  Declarer.test.<fn>.<fn>.<fn>

my .yaml is like

dependencies:
  json_annotation: ^1.0.0
dev_dependencies:
  build_runner: ^0.10.1+1
  dart_json_mapper: ^1.0.8
  test: ^1.5.1+1

downGrade intl PKG to ver : 16.0.0

Because dart_json_mapper >=1.3.3 depends on intl ^0.16.1 and every version of flutter_localizations from sdk depends on intl 0.16.0, dart_json_mapper >=1.3.3 is incompatible with flutter_localizations from sdk.

because flutter_localization depend on intl : 16.0.0 , so I can't localize my app.
because I want to use

JsonMapper().useAdapter(
    JsonMapperAdapter(
      valueDecorators: {
        typeOf<List<ContactModel>>(): (value) => value.cast<ContactModel>()
      },
    ),
  );

also because of #36

How to handle multiple models in difference files?

for example, there are two models in two files
modelA.dart

@jsonSerializable 
class A {
    int id;
    String name;
}
//It's seem must set this method in model file, right? if I not set it ,it can't generate the code :(
main() {
  initializeReflectable(); 
}

modelB.dart

@jsonSerializable 
class B {
    int id;
    String name;
}
//It's seem must set this method in model file, right?
main() {
  initializeReflectable(); 
}

and the program main file main.dart

void main() {
    //how can I init the json model here?
}

so, how can I reference these files and call the initializeReflectable();

thanks!

Provide default values?

Is there a way to provide default values? I'm migrating from json_serializable, and I was doing things like:

  @JsonKey(defaultValue: []) final List<Person> guardians;
  @JsonKey(defaultValue: {}) final Map<String, String> addresses;
  @JsonKey(defaultValue: false) final bool isRead;
  @JsonKey(defaultValue: false) final bool isArchived;

I'm not really seeing an equivalent way to do that with this library.

Can not serialize Map<String, T>

Hi is possible to serialize a map of a type?
For example:

@jsonSerializable
class Person {
   final int age;
   Person({this.age});
}

Map<String, Person> foo = Map();
foo['bar'] = Person(age: 30);
final json = JsonMapper.serialize(foo);

I have been trying this in several ways and I'm not able to get it, but yes I was able to do it with the library json_serializable. I thought this one could do the same stuff with less boilerplate.

Thanks!

Edit:
I get this error It seems your class '_InternalLinkedHashMap<String, Person>' has not been annotated with @jsonSerializable

Too many positional arguments on reflectable-2.2.1

Hi,

I got this error message that seems related to a dependency :

[SEVERE] Failed to snapshot build script .dart_tool/build/entrypoint/build.dart.
This is likely caused by a misconfigured builder definition.
[SEVERE] ../../flutter/.pub-cache/hosted/pub.dartlang.org/reflectable-2.2.1/lib/src/builder_implementation.dart:5207:46: Error: Too many positional arguments: 0 allowed, but 1 found.Try removing the extra positional arguments.  InterfaceType get type => InterfaceTypeImpl(this);                                             ^../../flutter/.pub-cache/hosted/pub.dartlang.org/analyzer-0.39.4/lib/src/dart/element/type.dart:705:3: Context: Found this candidate, but the arguments don't match.  InterfaceTypeImpl({  ^^^^^^^^^^^^^^^^^../../flutter/.pub-cache/hosted/pub.dartlang.org/reflectable-2.2.1/lib/src/builder_implementation.dart:5214:24: Error: Too many positional arguments: 0 allowed, but 1 found.Try removing the extra positional arguments.      InterfaceTypeImpl(this);                       ^../../flutter/.pub-cache/hosted/pub.dartlang.org/analyzer-0.39.4/lib/src/dart/element/type.dart:705:3: Context: Found this candidate, but the arguments don't match.  
InterfaceTypeImpl({  ^^^^^^^^^^^^^^^^^
pub finished with exit code 78

Overiding the dependency :
dependency_overrides:
reflectable: 2.2.0

[INFO] Running build completed, took 7.7s

Any idea why ?

Thanks

Parameter enumValues is probably ignored

Given this dummy code fragment:

import 'package:dart_json_mapper/json_mapper.dart';

import 'main.reflectable.dart';

enum OperationType { insert, update, remove }

const operationTypeValues = ["__insert", "__update", "__remove"];

@jsonSerializable
class XYZ {
  @JsonProperty(enumValues: operationTypeValues)
  OperationType operation = OperationType.insert;
}


void main() {
  initializeReflectable();


  var xyz = XYZ()..operation = OperationType.update;
  print(JsonMapper.serialize(xyz));

}

it will print

{
"operation": "OperationType.update"
}

So what is wrong? Why is actually enumValues needed?

RFC 6901 JSON pointer support for mapping names/paths

The NASA Images and Videos public API returns model with a complex structure:

{
  "href":"https://images-assets.nasa.gov/image/PIA22161/collection.json",
  "data":[
    {
      "date_created":"2018-01-09T00:00:00Z",
      "media_type":"image",
      "center":"JPL",
      "nasa_id":"PIA22161",
      "title":"Investigating Mars: Candor Chasma",
      "secondary_creator":"NASA/JPL-Caltech/ASU",
      "description":"This image shows part of western Candor and the erosion of a large mesa. Layered materials are visible throughout the image. The dark material with the linear appearance in the middle of the image are sand dunes. Sand dunes are created by wind action. At the present time, wind is the active process shaping the surface.  Candor Chasma is one of the largest canyons that make up Valles Marineris. It is approximately 810 km long (503 miles) and has is divided into two regions - eastern and western Candor. Candor is located south of Ophir Chasma and north of Melas Chasma. The border with Melas Chasma contains many large landslide deposits. The floor of Candor Chasma includes a variety of landforms, including layered deposits, dunes, landslide deposits and steep sided cliffs and mesas. Many forms of erosion have shaped Chandor Chasma. There is evidence of wind and water erosion, as well as significant gravity driven mass wasting (landslides).  The Odyssey spacecraft has spent over 15 years in orbit around Mars, circling the planet more than 69000 times. It holds the record for longest working spacecraft at Mars. THEMIS, the IR/VIS camera system, has collected data for the entire mission and provides images covering all seasons and lighting conditions. Over the years many features of interest have received repeated imaging, building up a suite of images covering the entire feature. From the deepest chasma to the tallest volcano, individual dunes inside craters and dune fields that encircle the north pole, channels carved by water and lava, and a variety of other feature, THEMIS has imaged them all. For the next several months the image of the day will focus on the Tharsis volcanoes, the various chasmata of Valles Marineris, and the major dunes fields. We hope you enjoy these images!  Orbit Number: 6245 Latitude: -5.77639 Longitude: 284.339 Instrument: VIS Captured: 2003-05-12 14:49  https://photojournal.jpl.nasa.gov/catalog/PIA22161",
      "keywords":[
        "2001 Mars Odyssey",
        "Mars"
      ],
      "description_508":"This image captured by NASA's 2001 Mars Odyssey spacecraft shows part of western Candor and the erosion of a large mesa. Layered materials are visible throughout the image."
    }
  ],
  "links":[
    {
      "rel":"preview",
      "href":"https://images-assets.nasa.gov/image/PIA22161/PIA22161~thumb.jpg",
      "render":"image"
    }
  ]
}

It's really great this library supports nested objects like @JsonProperty(name: 'baz/items') but does it support List as well?

In my use case, I'd like to do something like: @JsonProperty(name: 'data/0/title').

Add ignore 'implementation_imports'

In the generated main.reflectable.dart, I presume the following can be added to reduce the numbers of problems :
// ignore_for_file: implementation_imports

Regards

Serialization issue with 2 of the same object

Hi,

User user = User();
    Device d = Device(uuid: Uuid());
    user.devices = [];
    user.devices.add(d);
    user.devices.add(d);
    print(JsonMapper.serialize(user));

This genrerate a serialization error :

`E/flutter (31538): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method '&' was called on null.
E/flutter (31538): Receiver: null
E/flutter (31538): Tried calling: &(4294967295)
E/flutter (31538): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter (31538): #1 new Color (dart:ui/painting.dart:107:42)
E/flutter (31538): #2 WidgetConfigurationModel.backgroundColor/…/models/widget_configuration_model.dart:23
E/flutter (31538): #3 _data./main.reflectable.dart:3587
E/flutter (31538): #4 _InstanceMirrorImpl.invokeGetter
package:reflectable/src/reflectable_builder_based.dart:340
E/flutter (31538): #5 JsonMapper.enumeratePublicFields
package:dart_json_mapper/src/mapper.dart:287
E/flutter (31538): #6 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:453
E/flutter (31538): #7 JsonMapper.serializeObject.
package:dart_json_mapper/src/mapper.dart:464
E/flutter (31538): #8 JsonMapper.enumeratePublicFields
package:dart_json_mapper/src/mapper.dart:298
E/flutter (31538): #9 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:453
E/flutter (31538): #10 JsonMapper.serializeObject.
package:dart_json_mapper/src/mapper.dart:420
E/flutter (31538): #11 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:29)
E/flutter (31538): #12 ListIterable.toList (dart:_internal/iterable.dart:221:19)
E/flutter (31538): #13 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:420
E/flutter (31538): #14 JsonMapper.serializeObject.
package:dart_json_mapper/src/mapper.dart:464
E/flutter (31538): #15 JsonMapper.enumeratePublicFields
package:dart_json_mapper/src/mapper.dart:298
E/flutter (31538): #16 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:453
E/flutter (31538): #17 JsonMapper.serializeObject.
package:dart_json_mapper/src/mapper.dart:464
E/flutter (31538): #18 JsonMapper.enumeratePublicFields
package:dart_json_mapper/src/mapper.dart:298
E/flutter (31538): #19 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:453
E/flutter (31538): #20 JsonMapper.serializeObject.
package:dart_json_mapper/src/mapper.dart:420
E/flutter (31538): #21 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:29)
E/flutter (31538): #22 ListIterable.toList (dart:_internal/iterable.dart:221:19)
E/flutter (31538): #23 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:420
E/flutter (31538): #24 JsonMapper.serializeObject.
package:dart_json_mapper/src/mapper.dart:464
E/flutter (31538): #25 JsonMapper.enumeratePublicFields
package:dart_json_mapper/src/mapper.dart:298
E/flutter (31538): #26 JsonMapper.serializeObject
package:dart_json_mapper/src/mapper.dart:453
E/flutter (31538): #27 JsonMapper.serialize
package:dart_json_mapper/src/mapper.dart:63
E/flutter (31538): #28 User.toJson/…/models/user_model.dart:72
E/flutter (31538): #29 UserRepositories.updateUser/…/repositories/user_repositories.dart:60
E/flutter (31538): #30 UserService.updateUser/…/services/user_service.dart:170
E/flutter (31538): #31 UserService.broadcastPlayListOnDevice/…/services/user_service.dart:166
E/flutter (31538): #32 _DevicePlayListViewState.selectPlayList/…/playlist/device_playlist_view.dart:44
E/flutter (31538): #33 _PlayListBottomBarState.selectPlayList/…/widgets/playlist_bottom_bar.dart:25
E/flutter (31538): #34 _PlaylistSelectionCardState.build./…/widgets/playlist_selection_card.dart:30
E/flutter (31538): #35 _InkResponseState._handleTap
package:flutter/…/material/ink_well.dart:706
E/flutter (31538): #36 _InkResponseState.build.
package:flutter/…/material/ink_well.dart:789
E/flutter (31538): #37 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:182
E/flutter (31538): #38 TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:486
E/flutter (31538): #39 BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:264
E/flutter (31538): #40 BaseTapGestureRecognizer.acceptGesture
package:flutter/…/gestures/tap.dart:236
E/flutter (31538): #41 GestureArenaManager.sweep
package:flutter/…/gestures/arena.dart:156
E/flutter (31538): #42 GestureBinding.handleEvent (package:flutter/src `

Let me know if you need more information.

How to use ObservableList with json from api

import 'package:mobx/mobx.dart';
import 'package:dart_json_mapper/dart_json_mapper.dart';
part 'test_dart_json_map.g.dart';

@jsonSerializable
class TestItem with Store{
  int id;
 
  @observable
  String content;

  TestItem({this.id, this.content});
}

@jsonSerializable
class TestChain = _TestChain with _$TestChain;

@jsonSerializable
abstract class _TestChain with Store {
  final json = [ // from api response
    {
      'id': 1,
      'content': '1'
    },
    {
      'id': 2,
      'content': '2'
    },
  ];

  ObservableList<TestItem> mailingList = ObservableList<TestItem>();
  _TestChain(this.mailingList);
  final result = JsonMapper.serialize(
    TestChain(ObservableList<TestItem>.of(json)) // there is an error
  );

  @action 
  addItem(TestItem item) {
    mailingList.add(item);
  }
  @action 
  changeItem() {
    mailingList[0].content = 'change';
  }
}

expect:
i want use json(from api) to convert ObservableList
error:
type 'ObservableList<String>' is not a subtype of type 'ObservableList<TestItem>' of 'function

Deserializing with base type as parameter using @Json(typeNameProperty: ' ') throws exception

This currently throws the following exception:

It seems your class 'User' has not been annotated with @jsonSerializable

But we are never serializing or deserializing the User class itself, only the UserImpl class. The UserImpl class picks up the type from the JSON. So there would be no need to annotate the user class, when Serializer can detect the concret type in the JSON?

  test('User can be serialized and deserialized', () {
    User user = UserBuilder().build();
    var map = JsonMapper.toMap(user);
    var newUser = JsonMapper.fromMap<User>(map);
  });
abstract class User extends DataModel {
  final Email email;

  User copyWith({
    String id,
    Email email,
  });

  factory User(String id) =  UserImpl.newUser;
}

@Json(typeNameProperty: 'type')
@jsonSerializable
class UserImpl extends DataModel implements User {
  final Email email;

  UserImpl(
      {String id,
      this.email})
      : super(id: id);

  factory UserImpl.newUser(
      String id) {
    return UserImpl(
      id: id,
    );
  }

  @override
  User copyWith(
      {Email email,
      String id}) {
    return UserImpl(
        id: id ?? this.id,
        email: email ?? this.email);
  }
}

Failed when try to work with complex objects (not String, num, etc)

When i try to serialize something more complex then primitive i got error like that

Converting object to an encodable object failed: Instance of 'Pt'

my test code:

@jsonSerializable
class Base<T> {
  final T value;
  Base(this.value);
}

@jsonSerializable
class Pt {
  Pt();
}

@jsonSerializable
class PtDerived extends Base<Pt>{
  PtDerived(Pt value) : super(value);
}

void main() {
  initializeReflectable(); // Imported from main.reflectable.dart
    var pt = Pt();
    print(JsonMapper.serialize(pt));
    var s2 = JsonMapper.serialize(PtDerived(pt));
    print(s2);
...

Ignore Unknown Types during serialization

Hi @k-paxian,

I was afraid you got bored, so I found you a new issue 😂

My Map (Firebase) has a DateTime field but it's not present on my Model, but JsonMapper still want to deserialize it :
JsonUnsupportedObjectError (Converting object to an encodable object failed: Instance of 'Timestamp')

Was able to reproduce it with this exemple :

import 'package:dart_json_mapper/dart_json_mapper.dart';

enum MyColor { black, red }

@jsonSerializable
class MyCarModel {
  const MyCarModel({this.model});

  final String model;

  Map<String, dynamic> toJson() {
    return JsonMapper.toMap(this);
  }
}
// given
final Map<String, dynamic> json = <String, dynamic>{
   'model': 'Tesla',
   'DateFacturation': Timestamp(1568465485, 0),
};

// when
final MyCarModel myModel = JsonMapper.fromMap(json);

// then
expect(myModel.model, 'Tesla');

Regards

using deep nested collections at dart_json_mapper_mobx

I can't guess what I'm doing wrong, here is my json

[
  {
    "title": "Salads & Dips",
    "items": [
      {
        "id": "1",
        "title": "Columbia Salad",
      }
    ]
  }
]

and mobx stores

@jsonSerializable
class MenuSectionStore extends _MenuSectionStore with _$MenuSectionStore {

}

abstract class _MenuSectionStore with Store {
  @observable
  String title = '';

  @observable
  @JsonProperty(ignoreIfNull: true)
  ObservableList<MenuItemStore> items = ObservableList<MenuItemStore>();
}


@jsonSerializable
class MenuItemStore extends _MenuItemStore with _$MenuItemStore {

}

abstract class _MenuItemStore with Store {
  @observable
  String id;

  @observable
  String title = '';
}

JsonMapper().useAdapter(
      mobXAdapter
    );

// this string is works
JsonMapper.deserialize<MenuSectionStore>(jsonResponse[0]);
// this cause error
JsonMapper.deserialize<ObservableList<MenuSectionStore>>(jsonResponse);

errors is

[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'MenuItemStore' of 'element' #0 ObservableList.add (package:mobx/src/api/observable_collections/observable_list.dart) #1 IterableConverter.fromJSON.<anonymous closure> (package:dart_json_mapper_mobx/dart_json_mapper_mobx.dart:181:57) #2 List.forEach (dart:core-patch/growable_array.dart:282:8) #3 IterableConverter.fromJSON (package:dart_json_mapper_mobx/dart_json_mapper_mobx.dart:181:19) #4 JsonMapper.deserializeObject (package:dart_json_mapper/src/mapper.dart:549:38) #5 JsonMapper.deserialize (package:dart_json_mapper/src/mapper.dart:46:21)

Serializing null DateTime

Hi, the serialization of a null DateTime is wrong. It is serialized as { "data": "null" } (as String) instead of { "data": null }.

Below is a test case:

@jsonSerializable
class Model {
    DateTime data;
}


void main() {
  initializeReflectable();
  var a = Model();
  var b = JsonMapper.toJson(a);
  print(b);
  var c = JsonMapper.fromJson<Model>(b);
}

The last line, correctly, throws the error:

FormatException (FormatException: Invalid date format null)

Can't deserialize when value of nested object is null.

There is classes like this:

@jsonSerializable
class Foo {
  final Bar bar;
  final String message;

  Foo(this.bar, this.message);
}

@jsonSerializable
class Bar {
  final Baz baz;

  Bar(this.baz);
}

@jsonSerializable
class Baz {}

and json:

{ "message": "hello world" }
// { "message": "hello world", "bar": null } also

I get the following error:

NoSuchMethodError: The method 'containsKey' was called on null.
Receiver: null
Tried calling: containsKey("baz")

dart:core                                         Object.noSuchMethod
package:dart_json_mapper/json_mapper.dart 355:19  JsonMapper.getPositionalArguments.<fn>
package:dart_json_mapper/json_mapper.dart 316:14  JsonMapper.enumerateConstructorParameters.<fn>
dart:core                                         List.forEach
package:dart_json_mapper/json_mapper.dart 302:29  JsonMapper.enumerateConstructorParameters
package:dart_json_mapper/json_mapper.dart 351:5   JsonMapper.getPositionalArguments
package:dart_json_mapper/json_mapper.dart 447:30  JsonMapper.deserializeObject
package:dart_json_mapper/json_mapper.dart 459:22  JsonMapper.deserializeObject.<fn>
package:dart_json_mapper/json_mapper.dart 285:14  JsonMapper.enumeratePublicFields
package:dart_json_mapper/json_mapper.dart 451:5   JsonMapper.deserializeObject
package:dart_json_mapper/json_mapper.dart 51:21   JsonMapper.deserialize
test/model_test.dart 12:26                        main.<fn>

I think, the JsonMapper need to check the jsonMap is null before instantiating object.(json_mapper.dart 445)

Hot to avoid CircularReferenceError

I need to serialize the same object multiple times into the same object. It is a stamp, which is copied to both a start field and an edit field. However I get a CircularReferenceError

Failed serializing enum on extended class

Given this sample:

import 'package:dart_json_mapper/annotations.dart';
import 'package:dart_json_mapper/json_mapper.dart';

import 'main.reflectable.dart';

enum OperationType { insert, update, remove }


@jsonSerializable
class Change {
  String path;
  @JsonProperty(enumValues: OperationType.values)
  OperationType operation;
  Change({this.path, this.operation});
}

@jsonSerializable
class ContentChange extends Change {
  Map<String, dynamic> value;
  ContentChange({String path, OperationType operation, this.value})
      : super(path: path, operation: operation);
}

@jsonSerializable
class UpdateChange extends ContentChange {
  UpdateChange({String path, Map<String, dynamic> item})
      : super(path: path, operation: OperationType.update, value: item);
}

void main() {
  initializeReflectable();

  var change = Change(operation: OperationType.update, path: "info");
  var contentChange = ContentChange(operation: OperationType.update, path: "info", value: {"name": "newName"});
  var updateChange = UpdateChange(path: "info", item: {"name": "newName"});

  // this is OK
  var serialized = JsonMapper.serialize(change);
  print("serialized change:$serialized");

  // this will throw error!!!
  serialized = JsonMapper.serialize(contentChange);
  print("serialized contentChange:$serialized");

  // also error
  serialized = JsonMapper.serialize(updateChange);
  print("serialized updateChange:$serialized");
}

This will print:

> serialized change:{
>  "path": "info",
>  "operation": "OperationType.update"
> }
> Unhandled exception:
> It seems your Enum class field is missing annotation:
> @JsonProperty(enumValues: OperationType.values)
> #0      JsonMapper.serializeObject (package:dart_json_mapper/json_mapper.dart:448:9)
> #1      JsonMapper.serializeObject.<anonymous closure> (package:dart_json_mapper/json_mapper.dart:467:28)
> #2      JsonMapper.enumeratePublicFields (package:dart_json_mapper/json_mapper.dart:303:14)
> #3      JsonMapper.serializeObject (package:dart_json_mapper/json_mapper.dart:456:5)
> #4      JsonMapper.serialize (package:dart_json_mapper/json_mapper.dart:48:37)
> #5      main (file:///home/fidlip/dev/wspace/json_mapper_test/bin/main.dart:53:27)
> #6      _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:289:19)
> #7      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
> 
> 

Is it intended to support classes with enums inherited from parent class?

Tested on:
v. 1.6
SDK 2.1.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.