To remove a property from deserialization with Moshi, I need to use the Kotlin's @Transient annotation. However, I use a property without a backing field (with custom getter and setter), and therefore doesn't have any backing field and can't use @Transient.
One solution I thought about is doing a custom JsonAdapter that would skip the deserialization of this property. It is easy to skip serialization using skipValue(), but the fromJson function needs to return something, which will set the property.
How can I correct that?
Should properties without backing fields be skipped when serializing/deserializing the class?
What happens if you define the property as an extension? Like so?
https://github.com/square/moshi/pull/612
I didn't think about doing this at first! It works well! However, I think it is cleaner to define a val property along with a custom setter function, like so:
val vegetable: String get() = "Potato"
fun setVegetable(vegetable: String) {
this.vegetable = vegetable
}
The 4 issues that I found with using an extension property are:
I still think it would be great to be able to exclude properties without backing field from serialization/deserialization. If not automatically, maybe with a custom annotation.
Yeah, you're right. Need to find the right API.
Is there a plan to fix this? We couldn't migrate to Moshi because of this.
I'm running into this as well. Cannot apply @Transient to getters without backing fields.
Gson seems to ignore the non-backed kotlin fields without issue. Maybe there's a clue there on how to detect and ignore these?
Gson has basically zero understanding of kotlin, anything "working" there is coincidental
This is a huge issue for our team as well. A class-wide option for the codegen to ignore properties without backing fields would be life-saving for now.
So, until this enhancement has been implemented, here's an ugly hack you could use:
You can just reference the backing field in either the getter or the setter, without actually using it.
That way Kotlin will allow you to use @Transient and Moshi will ignore your computed property.
Please note that even though your property will be used as a computed property, it will still have to be initialized if you reference its backing field.
Example:
@Transient
val myComputedProperty: String = "" // Initialization is required.
get() {
field // Backing field reference so that @Transient may be allowed.
return "I am computed"
}
Most helpful comment
Gson has basically zero understanding of kotlin, anything "working" there is coincidental