I get following error, when i want to deserialize an object with a property of type List<> containing another serializeable object. If i change "ChatMember.fromJson(e as Map
E/flutter (21470): [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
E/flutter (21470): type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast
E/flutter (21470): #0 Object._as (dart:core/runtime/libobject_patch.dart:78:25)
E/flutter (21470): #1 _$ChatFromJson.<anonymous closure> (file:///C:/Flutter/src/hapi/lib/datamodels/chat.g.dart:13:56)
E/flutter (21470): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:414:29)
E/flutter (21470): #3 ListIterable.toList (dart:_internal/iterable.dart:219:19)
E/flutter (21470): #4 _$ChatFromJson (file:///C:/Flutter/src/hapi/lib/datamodels/chat.g.dart:14:13)
E/flutter (21470): #5 new Chat.fromJson (package:hapi/datamodels/chat.dart:22:55)
E/flutter (21470): #6 ChatsModel.getChats.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:hapi/models/chats_model.dart:24:72)
E/flutter (21470): #7 FirestoreHelper.fromListToMap.<anonymous closure> (package:hapi/framework/helper/firestorehelper.dart:8:36)
E/flutter (21470): #8 MapBase._fillMapWithMappedIterable (dart:collection/maps.dart:67:32)
E/flutter (21470): #9 new LinkedHashMap.fromIterable (dart:collection/linked_hash_map.dart:124:13)
E/flutter (21470): #10 FirestoreHelper.fromListToMap (package:hapi/framework/helper/firestorehelper.dart:6:16)
E/flutter (21470): #11 ChatsModel.getChats.<anonymous closure>.<anonymous closure> (package:hapi/models/chats_model.dart:24:31)
E/flutter (21470): #12 _RootZone.runUnaryGuarded (dart:async/zone.dart:1314:10)
E/flutter (21470): #13 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
E/flutter (21470): #14 _DelayedData.perform (dart:async/stream_impl.dart:591:14)
E/flutter (21470): #15 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:707:11)
E/flutter (21470): #16 _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:667:7)
E/flutter (21470): #17 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (21470): #18 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'chat.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Chat _$ChatFromJson(Map<String, dynamic> json) {
return Chat(
members: (json['members'] as List)
?.map((e) =>
e == null ? null : ChatMember.fromJson(e as Map<String, dynamic>))
?.toList(),
memberIds: (json['memberIds'] as List)?.map((e) => e as String)?.toList())
..creation = json['creation'] == null
? null
: DateTime.parse(json['creation'] as String)
..lastUpdate = json['lastUpdate'] == null
? null
: DateTime.parse(json['lastUpdate'] as String);
}
Map<String, dynamic> _$ChatToJson(Chat instance) => <String, dynamic>{
'creation': instance.creation?.toIso8601String(),
'lastUpdate': instance.lastUpdate?.toIso8601String(),
'members': instance.members,
'memberIds': instance.memberIds
};
Workaround:
factory Chat.fromJson(Map<String, dynamic> json) {
json["members"] = (json['members'] as List)
?.map((e) =>
e == null ? null : Map<String, dynamic>.from(e))
?.toList();
return _$ChatFromJson(json);
}
Duplicate of https://github.com/flutter/flutter/issues/17417 – I'll try to take a look today...
Actually, it looks like the map is coming from package:hapi – not sure what that is.
You can configure your generator to use anyMap – see https://pub.dartlang.org/packages/json_serializable under Build Configuration – set any_map: true and you should be good!
Or change your map generation to create Map<String, dynamic> instead of Map<dynamic, dynamic>
Tried any_map: true. But this didn't changed anything. Only working with the provided workaround.
Glad you figured it out!
@kevmoo Sorry, for the unclear answer. Setting any_map: true didn't change anything, this did not solved my problem.
If the generated code didn't change at all, then you likely have something wrong with your configuration.
I couldn't get any_map to work either. However, I tried nullable: false and that fixed the problem for me
neither nullable: false nor anyMap: true worked for me, but the original workaround did.
In my case, I had a Map of another serializable object. My workaround in the fromJson method was as follows:
json["owner"] = Map<String, dynamic>.from(json["owner"]);
Running into this now. It's immediately apparent when trying to serialize JSON from firebase_database for some reason.
type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast
None of these works.
Print statement shows a map coming through.
contentRef(schemaKey)
.child(entryId)
.once()
.then((snap) => Entry.fromJson(snap.value.cast<String, dynamic>()));
contentRef(schemaKey)
.child(entryId)
.once()
.then((snap) => Entry.fromJson(Map.from(snap.value)));
contentRef(schemaKey).child(entryId).once().then(
(snap) => Entry.fromJson(Map<String, dynamic>.from(snap.value)));
using
firebase_database: ^2.0.1+1
json_serializable: ^2.0.2
See https://github.com/flutter/flutter/issues/17417 – please add a 👍 there to encourage the flutter folks to run on it
Thanks @kevmoo , I was able to move forward by using any_map: true and switching to MyClass.fromJson(Map json) instead of MyClass.fromJson(Map<String, dynamic> json)
Only this was my solution
Map data = jsonDecode(result.body);
List<dynamic> list = List();
list = data["result"].map((result) => new MyModel.fromJson(result)).toList();
for(int b=0;b<list.length;b++)
{
MyModel myModel = list[b] as MyModel;
_add(myModel);
}
factory MyModel.fromJson(Map<String, dynamic> json) {
return new MyModel(
id: json['id'],
name: json['name']
);
}
neither
nullable: falsenoranyMap: trueworked for me, but the original workaround did.In my case, I had a Map of another serializable object. My workaround in the
fromJsonmethod was as follows:
json["owner"] = Map<String, dynamic>.from(json["owner"]);
The best idea to Fix The Error
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>' in type cast
From jsonDecode("[]") as List<Map<String, dynamic>> To List<Map<String, dynamic>>.from(jsonDecode("[]"))
When argument data pass through by MethodChannel or EventChannel. we should use codec _JSONMethodCodec_ which will ensure type as Map
I think the issue is related to
https://github.com/flutter/flutter/issues/17417#issuecomment-431616591
On Wed, Jul 31, 2019 at 7:28 PM esonchen notifications@github.com wrote:
When argument data pass through by MethodChannel or EventChannel. we
should use codec JSONMethodCodec which will ensure type as Mapdynamic> automatically. —
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/json_serializable/issues/351?email_source=notifications&email_token=AAAEFCSPCOG74EJNMYYANXLQCJC6JA5CNFSM4F6HYP6KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3JDPSA#issuecomment-517093320,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAEFCTIAD62YE4G2HJRC23QCJC6JANCNFSM4F6HYP6A
.
Workaround:
factory Chat.fromJson(Map<String, dynamic> json) { json["members"] = (json['members'] as List) ?.map((e) => e == null ? null : Map<String, dynamic>.from(e)) ?.toList(); return _$ChatFromJson(json); }
Thanks, I skipped this answer almost 10 times. You saved my life. Huge appreciate. 👍
This problem is still apparent and it's very annoying. If you try to unwrap any nested maps from Realtime Database it falls apart. Furthermore, the errors provided for some reason do not show stack into json_serializable, so it's very difficult to track down the source.
https://github.com/FirebaseExtended/flutterfire/issues/833
Was this fixed? There's nothing to do here, sady...
On Mon, Feb 22, 2021 at 6:19 PM Luke Pighetti notifications@github.com
wrote:
This problem is still apparent and it's very annoying. If you try to
unwrap any maps from Realtime Database it falls apart.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/google/json_serializable.dart/issues/351#issuecomment-783818667,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAEFCS5YW6R3Q72FNLDJD3TAMGBJANCNFSM4F6HYP6A
.
Just for the sake of my understanding, is there any reason why json_serializable can't do a Map<String,dynamic>.from() when it's expecting a map? Would that resolve the issue?
I suspect I'm going to have to make a visitor to mutate nested maps into Map<String,dynamic> to coerce these realtime database response objects into something palatable for json_serializable
If I edit the json_serliazble code to change e as Map<String,dynamic> to Map<String,dynamic>.from(e) it works as expected
As implemented
_$_FBList _$_$_FBListFromJson(Map<String, dynamic> json) {
return _$_FBList(
info: json['info'] == null
? null
: FBListInfo.fromJson(json['info'] as Map<String, dynamic>),
members: (json['members'] as Map<String, dynamic>)?.map(
(k, e) => MapEntry(k,
e == null ? null : FBListMember.fromJson(e as Map<String, dynamic>)),
),
items: (json['items'] as Map<String, dynamic>)?.map(
(k, e) => MapEntry(
k, e == null ? null : FBListItem.fromJson(e as Map<String, dynamic>)),
),
);
}
Change to allow toJson to work with realtime database response objects.
_$_FBList _$_$_FBListFromJson(Map<String, dynamic> json) {
return _$_FBList(
info: json['info'] == null
? null
: FBListInfo.fromJson(json['info'] as Map<String, dynamic>),
members: (json['members'] as Map<String, dynamic>)?.map(
(k, e) => MapEntry(
k,
e == null
? null
: FBListMember.fromJson(Map<String, dynamic>.from(e))),
),
items: (json['items'] as Map<String, dynamic>)?.map(
(k, e) => MapEntry(k,
e == null ? null : FBListItem.fromJson(Map<String, dynamic>.from(e))),
),
);
}
I was able to get it to work with a combination of things
any_map: true
factory FBList.fromJson(Map<String, dynamic> json) => _$FBListFromJson(json);
FBList.fromJson(Map.from(listPayload))
But I am still curious to hear your thoughts about the solution in my previous comment.
Yeah any_may is your best bet here.
The problem w/ your proposal is it copies data unnecessarily. I guess we could do a cast. But it drives me nuts to create these types of work-arounds for other folks code.
I'm going to consider this resolved, thanks for the reply.
Most helpful comment
See https://github.com/flutter/flutter/issues/17417 – please add a 👍 there to encourage the flutter folks to run on it