I have issue when using Klaxon 5.5
Class :
data class QRResponse(
#field:SerializedName("qrType")
val qrType: String? = null,
#field:SerializedName("qrData")
val qrData: String? = null
)
Code :
val dataContents = result.contents
Log.d("ScanQRData", "result.contents : $dataContents")
val dataQR = Klaxon().parse<QRResponse>(dataContents)
Log.d("ScanQRData", "dataQR : $dataQR")
Result :
ScanQRData: result.contents : {"qrType": "product", "qrData":"352307811"}
ScanQRData: dataQR : QRResponse(qrType=null, qrData=null)
Any suggestion what happened to qrType and qrData null after parse from Klaxon?
Klaxon doesn't process #field:SerializedName annotation (where you have imported it from?). The correct way to customize mapping between your JSON documents and Kotlin objects in Klaxon is #Json annotation:
data class QRResponse(
#Json(name = "qrType")
val qrType: String? = null,
#Json(name = "qrData")
val qrData: String? = null
)
Related
I'm trying to assign a string value to an string attribute part of a data class object and it's not working:
appointmentInfo.mySymptoms?.medsDescription = "string description"
where,
data class AppointmentInfo(var id : Int? = null,
var planType : String? = null,
var dateFormat : DateFormat,
var mySymptoms : MySymptoms? = null) : Parcelable
#Parcelize
data class MySymptoms(var grantAccess : Boolean,
var takingMeds : Boolean,
var medsDescription : String? = null,
var symptomList : List<String>? = null,
var symptomsDescription : String? = null,
var generalDescription : String? = null ```
**appointmentInfo.mySymptoms?.medsDescription is always null**
Make sure the variables are assigned properly.
Code
data class AppointmentInfo(
var mySymptoms : MySymptoms? = null,
)
data class MySymptoms(
var medsDescription : String? = null,
)
fun main() {
var appointmentInfo = AppointmentInfo()
appointmentInfo.mySymptoms = MySymptoms()
appointmentInfo.mySymptoms?.medsDescription = "string description"
println(appointmentInfo.mySymptoms?.medsDescription)
}
Output
string description
Kotlin Playground link
You should use copy() function of data class https://kotlinlang.org/docs/data-classes.html#copying as Jet Brains suggests all data class member should be read only val
I am trying to create a JSON adapter for the following json
{
"message": {
"affenpinscher": [],
"african": [],
"airedale": [],
"akita": [],
"appenzeller": [],
"australian": [
"shepherd"
]
},
"status": "success"
}
I have tried the following
#JsonClass(generateAdapter = true)
data class BreedList(
val message: HashMap<String,List<String>> = HashMap<String,List<String>>()
)
and
#JsonClass(generateAdapter = true)
data class BreedList(
val message: Breed
)
#JsonClass(generateAdapter = true)
data class Breed(
val breed: List<String>
)
But both scenarios give me the errors, is there a way to parse the following object, I need the key as well as the list from the response
There is no need to create a custom adapter.
To parse the JSON you posted:
data class Base (
#field:Json(name = "message")
val message : Message,
#field:Json(name = "status")
val status : String
)
data class Message (
#field:Json(name = "affenpinscher")
val affenpinscher : List<String>,
#field:Json(name = "african")
val african : List<String>,
#field:Json(name = "airedale")
val airedale : List<String>,
#field:Json(name = "akita")
val akita : List<String>,
#field:Json(name = "appenzeller")
val appenzeller : List<String>,
#field:Json(name = "australian")
val australian : List<String>
)
Note: instead of String you can use whatever data type you need or create custom classes like Message.
I have a data class in Kotlin - where there are 5-6 fields,
data class DataClass(
val attribute1: String?,
val attribute2: String?,
val attribute3: Boolean?
)
i can initialise the class with DataClass(attribute1="ok", attribute2=null, attribute3= null)
Is there any way to prevent null values in data class ?
Kotlin's type system uses ? to declare nullability. Your data class has fields which are nullable. You can prevent them from being null by removing the ? from their types:
data class DataClass(
val attribute1: String, // not `String?`
val attribute2: String, // not `String?`
val attribute3: Boolean // not `Boolean?`
)
fun main() {
// This line will compile
val tmp = DataClass(attribute1 = "", attribute2 = "", attribute3 = false)
// This line will not compile
val fail = DataClass(attribute1 = null, attribute2 = null, attribute3 = null)
}
I have the following data class in Kotlin:
import com.google.gson.annotations.SerializedName
data class RouteGroup(
#SerializedName("name") var name: String,
#SerializedName("id") var id: Int
)
Sometimes I need to create an object with both fields, sometimes with only one of them.
How can I do this?
EDIT
This is not the duplicate of this question: Can Kotlin data class have more than one constructor?
That question shows how to set a default value for a field. But in my case, I don't need to serialize the field with the default value. I want a field to be serialized only when I explicitly assign a value to it.
it is easy you have to use the nullable operator
import com.google.gson.annotations.SerializedName
data class RouteGroup #JvmOverloads constructor(
#SerializedName("name") var name: String? = null,
#SerializedName("id") var id: Int? = null
)
You may need something like this:
sealed class RouteGroup
data class RouteGroupWithName(
#SerializedName("name") var name: String
) : RouteGroup()
data class RouteGroupWithId(
#SerializedName("id") var id: Int
) : RouteGroup()
data class RouteGroupWithNameAndId(
#SerializedName("name") var name: String,
#SerializedName("id") var id: Int
) : RouteGroup()
EDIT 1:
Or you can use nullable fields and named parameters like this:
data class RouteGroup(
#SerializedName("name") var name: String? = null,
#SerializedName("id") var id: Int? = null
)
val routeGroupWithName = RouteGroup(name = "example")
val routeGroupWithId = RouteGroup(id = 2)
val routeGroupWithNameAndId = RouteGroup(id = 2, name = "example")
I have Ticket class:
data class Ticket(
var contact_email : String? = null,
var date_opened : LocalDateTime? = null
)
but I get error during read from string:
Caused by:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot
construct instance of java.time.LocalDateTime (no Creators, like
default construct, exist): no String-argument constructor/factory
method to deserialize from String value ('2017-11-13T06:40:00Z') at
[Source: UNKNOWN; line: -1, column: -1] (through reference chain:
rnd_classifier.model.Ticket["date_opened"])
I tried add annotations without success:
data class Ticket(
var contact_email : String? = null,
#JsonSerialize(using = ToStringSerializer::class)
#JsonDeserialize(using = LocalDateTimeDeserializer::class)
var date_opened : LocalDateTime? = null
)
How to fixed it?
Your issue is more about jackson rather than kotlin.
As stated in serialize/deserialize java 8 java.time with Jackson JSON mapper
you need to add an additional gradle dependency to solve it
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.5")
after that it should work
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import org.testng.annotations.Test
import java.time.LocalDateTime
class SoTest {
data class Ticket(
var contact_email: String? = null,
var date_opened: LocalDateTime? = null
)
#Test
fun checkSerialize() {
val mapper = ObjectMapper()
mapper.registerModule(JavaTimeModule())
val ticket = mapper.readValue(inputJsonString, Ticket::class.java)
assert ("$ticket"=="Ticket(contact_email=contact#ema.il, date_opened=2017-11-13T06:40)")
}
val inputJsonString = """{
"contact_email": "contact#ema.il",
"date_opened": "2017-11-13T06:40:00Z"
}""".trimIndent()
}