Tiago Nunes

    Tiago Nunes

    1 year ago
    Hi everyone, I'm consuming data from a JSON API. Some responses contain decimal numbers. Depending in the culture-info field sent to the server, they might use dots (e.g. 18.312) or commas (e.g. 18,312) Is there some way I can interpret these both as Float in my Serializer class (Float only accepts dot notation)? Maybe through some custom field desserialization or something...?
    Javier

    Javier

    1 year ago
    you can create a custom serializer for example
    Tiago Nunes

    Tiago Nunes

    1 year ago
    A custom serializer can receive a String and return a Float? How would I use it after creating it?
    Can a custom serializer for certain fields only?
    Oh I think i get it, I create a custom serializer, then I create a Serializable class CustomFloat with that serializer, and the fields will be of that type,right?
    Here you have a lot of examples
    I would use a specific class for that
    Do you need to handle that float in local?
    Or you are only going to show that string in the UI?
    Tiago Nunes

    Tiago Nunes

    1 year ago
    No, I'm not showing that string in the UI. I rather have it saved only as a Float and deal with Internationalization locally
    Javier

    Javier

    1 year ago
    then if it is a "real" float, I would create a custom class for that, but ideally backend should solve that
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Yeah but changing the backend is not an option, what you gona do 😒miling_face_with_tear:
    @Javier I have this
    object FloatAsDecimalString : KSerializer<Float> {
        override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Float", PrimitiveKind.STRING)
    
        override fun serialize(encoder: Encoder, value: Float) =
            encoder.encodeString(value.toString())
    
        override fun deserialize(decoder: Decoder): Float =
            decoder.decodeString().replace(",", ".").toFloat()
    }
    
    @Serializable
    data class ExampleResponse(
        val id: Long,
        val someDecimal: Float,
    )
    Now, how do I apply the Serializer?
    Javier

    Javier

    1 year ago
    @Serializable
    data class ExampleResponse(
        val id: Long,
        @Serializable(with = FloatAsDecimalString::class) val someDecimal: Float,
    )
    I think with that
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Json.decodeFromString<ExampleResponse>("""
        {
            "id": 1,
            "someDecimal": "1.31"
        }
    """)
    This gave me an error: java.lang.ExceptionInInitializerError at com.qmx.web.contract.response.ExampleResponse$$serializer.deserialize(Unknown Source:64) at com.qmx.web.contract.response.ExampleResponse$$serializer.deserialize(ExampleResponse.kt:24) at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:63) at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:33) at kotlinx.serialization.json.Json.decodeFromString(Json.kt:85)
    Javier

    Javier

    1 year ago
    this is working for me
    I changed the Float inside PrimitiveSerialDecriptor
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Why?
    Wow it worked for me too changing to "id"
    But why hahaha
    Javier

    Javier

    1 year ago
    I think because you cant use a type
    you can change that to whatever you want,
    sasdsadas
    should work too
    Tiago Nunes

    Tiago Nunes

    1 year ago
    There's probably a better descriptor for this use case then maybe? I don't know anything about descriptors yet...
    Javier

    Javier

    1 year ago
    probably that Serial name will create some code under the hood, and using Float or whatever existent type or reserved words is not a good idea
    I usually put the original property name, in this case I would put
    someDecimal
    ,
    Tiago Nunes

    Tiago Nunes

    1 year ago
    I'll put DecimalString. I think it makes sense, its a DecimalString, which is a String, that's the description of the field i guess hahaha
    Anyway, thanks a lot 🙌