Steve Gailey
Steve Gailey

Reputation: 128

Adding a parameter to Implicit Reads building a case class from JSON with Play

I need to add a static value to a case class I'm building from JSON with Play framework. I can add a constant value like this:

implicit val userRead: Reads[UserInfo] = (
  Reads.pure(-1L) and
  (JsPath \ "firstName").readNullable[String] and
  (JsPath \ "lastName").readNullable[String] 
)(UserInfo.apply _)

But I can't see how I could pass a variable into the implicit Reads at the time it is called. I'm pretty new to Scala so probably missing something obvious?

Upvotes: 1

Views: 680

Answers (2)

Bilk
Bilk

Reputation: 438

I'm assuming that your UserInfo is something like this:

case class UserInfo(id: Long, firstName: Option[String], lastName: Option[String])

You only need to tweak a bit userRead:

def userRead(id: Long): Reads[UserInfo] = (
  Reads.pure(id) and
  (JsPath \ "firstName").readNullable[String] and
  (JsPath \ "lastName").readNullable[String]
)(UserInfo.apply _)

And then make use of it explicitly when decoding the json:

json.as[UserInfo](userRead(12345L))

Or, alternatively, instantiate the Reads making it implicit:

implicit val userRead12345 = userRead(12345L)

json.as[UserInfo]

Upvotes: 2

pme
pme

Reputation: 14803

there is a simpler solution:

import play.api.libs.json._

add all values that have static default values at the end:

case class UserInfo(firstName:String, lastName:String, id:Long = -1)

Use play-json format with default values:

object UserInfo{

    implicit val jsonFormat: Format[UserInfo] = Json.using[Json.WithDefaultValues].format[UserInfo]
}

And use it like this

val json = Json.toJson(UserInfo("Steve", "Gailey"))

println(json.validate[UserInfo])

See here the whole example

Upvotes: 0

Related Questions