Moshi: Deserializing extended Kotlin class

Created on 9 Apr 2018  路  9Comments  路  Source: square/moshi

I'm trying to deserialize this JSON

{
  "derived_value": "foo",
  "parent_value": "bar"
}

with these classes

data class DerivedEntity(
    @Json(name = "derived_value") val derivedValue: String? = null
) : ParentEntity()
abstract class ParentEntity(
    @Json(name = "parent_value") val parentValue: String? = null
)

Result is instance of DerivedEntity class with values set to derivedValue = "foo" and parentValue = null.
It's possible to have parentValue also set to value from JSON?

(I'm able to achieve it by changing parentValue to var but I feel it's not correct solution.)

Most helpful comment

I'm surprised that this worked for you. In my case, for classes such as these:

@JsonClass(generateAdapter = true)
class Subclass(@Json(name="subclassPropertyJsonName") val subclassProperty: String? = null) : Superclass()

codegen ignored the annotations on Superclass. It started working when I specified the annotation target in the constructor:

abstract class Superclass(@property:Json(name="superclassPropertyJsonName") var superclassProperty: String? = null)

or moved the property to the class' body:

abstract class Superclass {
    @Json(name="superclassPropertyJsonName") var superclassProperty: String? = null
}

Thanks anyway!

All 9 comments

Working as intended.
Vals are read-only, so you probably want the parent_value as a constructor parameter or a var.
(Aside: Inheritance with value types is strange, and I'm surprised Kotlin data classes allow this behavior.)

Unfortunately our API send some common parameters in every response so inheritance was natural choice for me. At least var is working.

Thanks for answer, I think this issue can be closed.

@LukasVykuka could you post a code example that worked for you?

@SpaceBison having parent parameter as var (not val) make it work

abstract class ParentEntity(
    @Json(name = "parent_value") var parentValue: String? = null
)

@LukasVykuka do you use codegen to generate adapters or do you use the reflection-based runtime adapter factory?

@SpaceBison codegen

I'm surprised that this worked for you. In my case, for classes such as these:

@JsonClass(generateAdapter = true)
class Subclass(@Json(name="subclassPropertyJsonName") val subclassProperty: String? = null) : Superclass()

codegen ignored the annotations on Superclass. It started working when I specified the annotation target in the constructor:

abstract class Superclass(@property:Json(name="superclassPropertyJsonName") var superclassProperty: String? = null)

or moved the property to the class' body:

abstract class Superclass {
    @Json(name="superclassPropertyJsonName") var superclassProperty: String? = null
}

Thanks anyway!

@SpaceBison ups, sorry, I forgot that in production code I don't use anotations because JSON parameters have same names ParentEntity. That's why it worked.

But thanks for your hints, they are useful.

@SpaceBison

I filed https://github.com/square/moshi/issues/700 for that.

Was this page helpful?
0 / 5 - 0 ratings