Reputation: 139
I am trying to convert com.google.gson.JsonObject to case class object. Sometime some element in the record are missing in which case I want it to be assigned as None to case class member
object tmp {
case class person(name: String, age: Long)
def main(args: Array[String]): Unit = {
val parser = new JsonParser();
//PERSON 2
val record2 = parser.parse("""{"name":"xyz"}""").getAsJsonObject()
val record2_name = record2.get("name").getAsString.toLowerCase
val record2_age = if(record2.get("age") != null) record2.get("age") else None
val person2 = new person(record2_name,record2_age) //-> Type Mismatch, expected: Long, actual: Long
println(person2);
}
}
Upvotes: 0
Views: 2165
Reputation: 7383
You simply can't call a parameter of one type, age: Long
in your case, with an argument of a different type Option[Long]
.
At least this is what your question seems to imply.
You need to define the attributes that could be missing as Option
s.
e.g. in your example
case class person(name: String, age: Option[Long])
and then when you extract the json value you can make use of the Option.apply
method, that returns None
if the argument is null
…
val record2_age = Option(record2.get("age")).map(_.getAsLong) // None if get("age) returns null
…
val person2 = new person(record2_name,record2_age) //There should be no more type mismatch now
Upvotes: 1
Reputation: 31262
In your case record2_age
is of type JsonElement
which is simply of type java Object
, but since you are assigning None
to it, it becomes Any
WHICH you are trying to assign to type Long
.
Short answer would be ,
val person = new person(jsonObject.get("name").getAsString.toLowerCase,
Option(jsonObject.get("age")).map(_.getAsLong).getOrElse(0l))
This way if jsonObject.get("age")
is null, Option(null)
gives you None
, or if present you get Option(28)
= Some(28)
You probably want your age to be 0l
if empty. If you want it to be None
, then you can use Option[Long]
.
1) simpler way
class GsonCaseClassSpecs extends FunSpec {
describe("case class conversion") {
it("converts gson with name/age to case class") {
case class person(name: String, age: Long)
val parser = new JsonParser()
//case 1
val jsonObject : JsonObject = parser.parse("""{"name":"xyz"}""").getAsJsonObject
val age = jsonObject.get("age") match {
case null => None
case value => Some(value.getAsLong)
}
val person1 = new person(jsonObject.get("name").getAsString.toLowerCase, age.getOrElse(0l))
assert(person1.name == "xyz")
assert(person1.age == 0)
//case 2
val jsonObject2 : JsonObject = parser.parse("""{"name":"xyz", "age" : 28}""").getAsJsonObject
val age2 : Option[Long] = jsonObject2.get("age") match {
case null => None
case value => Some(value.getAsLong)
}
val person2 = new person(jsonObject2.get("name").getAsString.toLowerCase, age2.getOrElse(0l))
assert(person2.name == "xyz")
assert(person2.age == 28)
}
}
}
2) If you want to make the age to be Option[Long]
. Option[T]
can have Some(x)
or None
.
class CaseClassFunSpecs extends FunSpec {
it("converts json to case class with empty age"){
case class person(name: String, age: Option[Long])
val parser = new JsonParser()
val json = parser.parse("""{"name":"xyz"}""").getAsJsonObject()
val personInstance = new person(json.get("name").getAsString.toLowerCase,
Option(json.get("age")).map(_.getAsLong))
assert(personInstance.name == "xyz")
assert(personInstance.age == None)
// NOTE
// do not do personInstance.age.get which would throw
// None.get
// java.util.NoSuchElementException: None.get
// at scala.None$.get(Option.scala:347)
// at scala.None$.get(Option.scala:345)
//rather use pattern match
personInstance.age match {
case Some(x) => println("value = " + x)
case None => throw new RuntimeException("Age can not be empty.")
}
}
it("converts json to case class with non-empty age"){
case class person(name: String, age: Option[Long])
val parser = new JsonParser()
val json = parser.parse("""{"name":"xyz", "age" : 28}""").getAsJsonObject()
val personInstance = new person(json.get("name").getAsString.toLowerCase,
Option(json.get("age")).map(_.getAsLong))
assert(personInstance.name == "xyz")
assert(personInstance.age == Some(28))
assert(personInstance.age.get == 28) //.get gives you the value
}
}
Upvotes: 1