Search code examples
kotlinkotlinx.serialization

Parsing a field in Kotlin, which can be a string or an object


I encountered a problem when receiving data from the backend that the resulting field (for example, "somethingField") could be either a String or an Object with two Int lists. How can you parse such data correctly? I'm using kotlinx.serialization .

@Serializable
data class SomeObject(
    ...
    val somethingField: String or SometingObject
    ...
)

@Serializable
data class SomethingObject(
    val list1: List<Int>,
    val list2: List<Int>,
)

Solution

  • You can achieve this by using sealed classes. When the real type is one of the few available types, sealed classes are helpful in modeling constrained class hierarchies.

      import kotlinx.serialization.Serializable
    
      @Serializable
      sealed class SomethingField {
      @Serializable
      data class SomethingObject(val list1: List<Int>, val list2: List<Int>)             
      : SomethingField()
    
      @Serializable
      data class SomethingString(val value: String) : SomethingField()
      }
    
    
      @Serializable
      data class SomeObject(
      // ...
      val somethingField: SomethingField?,
      // ...
      )
    

    You can then use it in your fragment or activity like this

      val someObject: SomeObject?  // ... deserialize from JSON
    
      when (someObject.somethingField) {
      is SomethingField.SomethingObject -> {
        // Handle SomethingObject case
        val list1 = someObject.somethingField.list1
        val list2 = someObject.somethingField.list2
      }
      is SomethingField.SomethingString -> {
        // Handle SomethingString case
        val stringValue = someObject.somethingField.value
      }
      }
    

    This way, you can handle different cases based on the actual type of "somethingField".