Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

default value in kotlin data class not work when server send null for that value in moshi

I use Moshi for parse json from server. if server send null for item default value not set! but server not send that item default value set.

json:

{"percentChange": null,"change": "-2500.00","value": "130000","name": null}

data class:

@JsonClass(generateAdapter = true) data class Reference(val name:String? = "-",val value: Double,val change: Double,val percentChange: Double? = -10.0,)

but data for name and percentChange is null that should "-" for name and "-10.0" for percentChange. if server not send name and percentChange, default value work, but if send that null default value not work!

I use converter-moshi:2.4.0 and retrofit:2.4.0

like image 645
h.kelidari Avatar asked Nov 28 '18 09:11

h.kelidari


People also ask

Can data classes inherit Kotlin?

Data classes are the replacements of POJOs in Java. Hence, it is natural to think that they would allow for inheritance in Java and Kotlin. The inheritance of data classes in Kotlin doesn't execute well. Hence, it is advised not to use inheritance by extending the data class in Kotlin.

Can we make data class open in Kotlin?

Kotlin Data Class Requirements The parameters of the primary constructor must be marked as either val (read-only) or var (read-write). The class cannot be open, abstract, inner or sealed. The class may extend other classes or implement interfaces.

What are data classes in Kotlin explain with a proper example?

Data class is a simple class which is used to hold data/state and contains standard functionality. A data keyword is used to declare a class as a data class. Declaring a data class must contains at least one primary constructor with property argument (val or var).


1 Answers

This is working as intended because the null literal as a value for a key in JSON is semantically different than the absence of the key and value.

You can make a custom JsonAdapter for your use case.

@JsonClass(generateAdapter = true)
data class Reference(
  @Name val name: String = "-",
  val value: Double,
  val change: Double,
  val percentChange: Double? = -10.0
) {
  @Retention(RUNTIME)
  @JsonQualifier
  annotation class Name

  companion object {
    @Name @FromJson fun fromJson(reader: JsonReader, delegate: JsonAdapter<String>): String {
      if (reader.peek() == JsonReader.Token.NULL) {
        reader.nextNull<Unit>()
        return "-"
      }
      return delegate.fromJson(reader)!!
    }

    @ToJson fun toJson(@Name name: String): String {
      return name
    }
  }
}

@Test fun reference() {
  val moshi = Moshi.Builder()
      .add(Reference)
      .build()
  val adapter = moshi.adapter(Reference::class.java)
  val decoded = Reference("-", 130_000.toDouble(), (-2_500).toDouble(), null)
  assertThat(adapter.fromJson(
      """{"percentChange": null,"change": "-2500.00","value": "130000"}"""))
      .isEqualTo(decoded)
  assertThat(adapter.fromJson(
      """{"percentChange": null,"change": "-2500.00","value": "130000","name": null}"""))
      .isEqualTo(decoded)
}
like image 122
Eric Cochran Avatar answered Oct 11 '22 20:10

Eric Cochran