Reputation: 198418
I defined a user which has a "video" information:
case class User(name:String, video: Option[Video])
case class Video(title:String, url:String)
And we have such a json:
{
"name": "somename",
"video": {
"title": "my-video",
"url": "https://youtube.com/watch?v=123123"
}
}
I can use such code to parse it:
implicit def DecodeUser: DecodeJson[User] = for {
name <- as[String]("name")
video <- as[Option[Video]]("video")
} yield User(name, video)
implicit def DecodeVideo: DecodeJson[Option[Video]] = for {
titleOpt <- as[Option[String]]("title")
urlOpt <- as[Option[String]]("url")
} yield (titleOpt, urlOpt) match {
case (Some(title), Some(url)) => Video(title, url)
case _ => None
}
From the DecodeVideo
, you can see I just want to provide the video only if both "title" and "url" provided.
It's working well if the json contains "video" section. But if it doesn't, argonaut will report that "video" section is not provided.
How to make "video" optional?
Upvotes: 3
Views: 780
Reputation: 2205
I can't seem to figure out how your code integrates with argonaut. All instances of the method as[T]
don't seem to match the signature that you're using. Anyways, here's a similar problem and the solution:
object Test {
case class Video(title: String, url: String)
def test(titleOptIn: List[Option[String]], urlOptIn: List[Option[String]]): List[Option[Video]] = {
for {
titleOpt <- titleOptIn
urlOpt <- urlOptIn
} yield (titleOpt, urlOpt) match {
case (Some(title), Some(url)) => Some(Video(title, url))
case _ => None.asInstanceOf[Option[Video]]
}
}
def main(args: Array[String]): Unit = {
test(List(Some("t")), List(Some("u"), None)).foreach(println)
}
}
// Has Output:
// Some(Video(t,u))
// None
Specifically note that the yield comprehension should return an Option[String]
since your yield is likely to be wrapping the result in DecodeJson
just like my example wraps it in a List
. Note that asInstanceOf
on None is optional; IntelliJ complains if it's not there but it actually compiles just fine.
The specific thing that I believe you're missing is wrapping Video
in Some
.
Upvotes: -1