You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a basic polymorphic structure with a base interface Event and a subclass MessageEvent.
When I try to deserialize a json object (type MessageEvent) with a type discriminator as the base class (here Event), I get an error Serializer for class 'Event' is not found.. This is however expected, because I am targeting Kotlin/JS and Event is an interface (#1000).
But serializing and deserializing another class (Wrapper) with an attribute of type Event works fine. The json object gets a type discriminator and can be deserialized. Why is it possible to get the serializer for Event in this case?
To get a type discriminator and successfully serialize/deserialize a MessageEvent directly it is possible to specify the PolymorphicSerializer explicitly when calling encodeToString/decodeFromString like suggested in issue #1000. But this does not work with Lists and Arrays.
When serializing Lists and Arrays you can not explicitly specify the PolymorphicSerializer for the generic type, so there is no type discriminator in the json. Trying to deserialize fails with Serializer for class 'Event' is not found.. Is there a workaround for this problem?
To Reproduce
interfaceEvent {
val id:String
}
@Serializable
data classMessageEvent(
overridevalid:String,
valmessage:String,
) : Event
@Serializable
data classWrapper(
valevent:Event
)
val format =Json {
classDiscriminator ="type"
prettyPrint =true
ignoreUnknownKeys =true
serializersModule =SerializersModule {
polymorphic(Event::class) {
subclass(MessageEvent::class)
}
}
}
// This works fine, but why?val wrapperIn =Wrapper(MessageEvent("id3", "A wrapped message"))
val wrapperString = format.encodeToString(wrapperIn)
val wrapper:Wrapper= format.decodeFromString(wrapperString)
println(wrapper) // Wrapper(event=MessageEvent(id=id3, message=A wrapped message))// Also works fineval messageEventIn:Event=MessageEvent("id1", "This is a message")
val messageEventString = format.encodeToString(PolymorphicSerializer(Event::class), messageEventIn)
val event:Event= format.decodeFromString(PolymorphicSerializer(Event::class), messageEventString)
println(event) // MessageEvent(id=id1, message=This is a message)// This does not workval messageEventListIn =listOf(MessageEvent("id4", "hi"), MessageEvent("id4", "Hui"))
val messageEventListString = format.encodeToString(messageEventListIn)
// Json looks like this (no type discriminator)//[// {// "id": "id4",// "message": "hi"// },// {// "id": "id4",// "message": "Hui"// }//]val messageEventList :List<Event> = format.decodeFromString(messageEventListString) // errors with Serializer for class 'Event' is not foundprintln(messageEventList)
Environment
Kotlin version: 1.4.31
Library version: 1.1.0
Kotlin platforms: JS
Gradle version: 6.6.1
The text was updated successfully, but these errors were encountered:
As a workaround, you can use encodeToString(ListSerializer(PolymorphicSerializer(Event::class)), ...)
Regarding the issue: inline serializer<T>() (which is used in decodeToString) does not return correct polymorphic serializer on JS now, it's an issue. See also #1116 and #1078
sandwwraith
changed the title
Kotlin/JS Polymorphic (de-)serialization with Lists/Arrays.
serializer<T>() does not work on Kotlin/JS when T is an interface
Apr 20, 2021
Describe the issue
I have a basic polymorphic structure with a base interface
Event
and a subclassMessageEvent
.When I try to deserialize a json object (type
MessageEvent
) with a type discriminator as the base class (hereEvent
), I get an errorSerializer for class 'Event' is not found.
. This is however expected, because I am targeting Kotlin/JS andEvent
is an interface (#1000).But serializing and deserializing another class (
Wrapper
) with an attribute of typeEvent
works fine. The json object gets a type discriminator and can be deserialized. Why is it possible to get the serializer forEvent
in this case?To get a type discriminator and successfully serialize/deserialize a
MessageEvent
directly it is possible to specify thePolymorphicSerializer
explicitly when callingencodeToString
/decodeFromString
like suggested in issue #1000. But this does not work with Lists and Arrays.When serializing Lists and Arrays you can not explicitly specify the
PolymorphicSerializer
for the generic type, so there is no type discriminator in the json. Trying to deserialize fails withSerializer for class 'Event' is not found.
. Is there a workaround for this problem?To Reproduce
Environment
The text was updated successfully, but these errors were encountered: