From this issue we have an adapter that converts an explicit null to non-null:
class DefaultZeroAdapter {
@FromJson
@DefaultZero
fun fromJson(@Nullable jsonFloat: Float?): Float {
return jsonFloat ?: 0f
}
@ToJson
fun toJson(@DefaultZero jsonFloat: Float) = jsonFloat
}
Unfortunately our generated code forces the _source_ data to be non-null before it is passed to the adapter.
private val floatAtDefaultZeroAdapter: JsonAdapter<Float> =
moshi.adapter<Float>(Float::class.java, Types.getFieldJsonQualifierAnnotations(javaClass, "floatAtDefaultZeroAdapter")).nonNull()
This is a bug. I鈥檓 not completely convinced it鈥檚 worth fixing, however. The cost in complexity here is pretty high.
Not worth fixing? I don't mean to be rude but if you guys aren't gonna fix this then what do you mean when you state
"Moshi is a great JSON library for Kotlin. It understands Kotlin鈥檚 non-nullable types and default parameter values"???
@or-dvir my assumption is that most users don鈥檛 write adapters that coalesce null to non-null. I might be wrong about this!
I sure did :). Frontend devs have to deal with all kinds of broken apis. Of course it's not very hard to handle this null-to-value conversion at a later stage, but this adapter was so much cleaner.
The complexity is that you will have to treat all values as nullable first and then check if any custom adapters need this information? I wonder if there is any different use case for such a check.
I really need null values.
I have annotation called @SerializeNulls.
When that is present, in my factory I call serializeNulls() upon that adapter:
val nextAnnotations = Types.nextAnnotations(annotations, SerializeNulls::class.java)
?: return null
return moshi.adapter<Any>(type, nextAnnotations).serializeNulls()
What now happens in the code gen is, it appends nullSafe() to the end so the serializeNulls effect is gone.
@field:SerializeNulls
private val nullableStringAtSerializeNullsAdapter: JsonAdapter<String?> =
moshi.adapter<String?>(String::class.java, Types.getFieldJsonQualifierAnnotations(javaClass, "nullableStringAtSerializeNullsAdapter")).nullSafe()
Now my application is buggy because the backend assumes that values that are absent in patches just don't get updated.
So codegen doesn't work with nulls in the json? What's the point of default values other than insulating yourself from messy apis?
Check my answer here and see if it will help you
Most helpful comment
I sure did :). Frontend devs have to deal with all kinds of broken apis. Of course it's not very hard to handle this null-to-value conversion at a later stage, but this adapter was so much cleaner.
The complexity is that you will have to treat all values as nullable first and then check if any custom adapters need this information? I wonder if there is any different use case for such a check.