score:2
The "addresses" in User contains the address so you don't really need to send Map[User, List[Address]] back to client. The Json would be an array of serialized user objects and addresses is part of that. If you do want to send back a Map then the type Map[String, List[Address]] makes more sense in Json serialization context. Here is the code to generate Json for List[User]. The output looks like this
[
{
"id": 1,
"name": "John Doe",
"email": "john@email.com",
"addresses": [
{
"id": 1001,
"userId": 1,
"city": "Chicago"
},
{
"id": 1002,
"userId": 1,
"city": "New York"
}
]
},
{
"id": 2,
"name": "Jane Doe",
"email": "jane@email.com",
"addresses": [
{
"id": 1012,
"userId": 1,
"city": "Dallas"
}
]
}
]
Here is the code the would be in you controller. It has implicit Json formatters that are used by Json.toJson.
implicit object PkWrites extends Writes[Pk[Long]] {
def writes(key: Pk[Long]) = Json.toJson(key.toOption)
}
implicit object PkReads extends Reads[Pk[Long]] {
def reads(json: JsValue) = json match {
case l: JsNumber => JsSuccess(Id(l.value.toLong))
case _ => JsSuccess(NotAssigned)
}
}
implicit val AddressWrites: Writes[Address] = (
(JsPath \ "id").write[Pk[Long]] and
(JsPath \ "userId").write[Long] and
(JsPath \ "city").write[String]
)(unlift(Address.unapply))
implicit val AddressReads: Reads[Address] = (
(JsPath \ "id").read[Pk[Long]] and
(JsPath \ "userId").read[Long] and
(JsPath \ "city").read[String]
)(Address.apply _)
implicit val UserWrites: Writes[User] = (
(JsPath \ "id").write[Pk[Long]] and
(JsPath \ "name").write[String] and
(JsPath \ "email").write[String] and
(JsPath \ "addresses").write[List[Address]]
)(unlift(User.unapply))
def makeJson() = Action {
val johnAddr1 = Address(Id(1001), 1, "Chicago")
val johnAddr2 = Address(Id(1002), 1, "New York")
val janeAddr1 = Address(Id(1012), 1, "Dallas")
val john = User(Id(1), "John Doe", "john@email.com", List(johnAddr1, johnAddr2))
val jane = User(Id(2), "Jane Doe", "jane@email.com", List(janeAddr1))
Ok(Json.toJson(List(john, jane)))
// Ok(Json.toJson(map))
}
score:4
You can solve this problem by transforming your Map[User, List[Address]]
to a List[User]
, and the JsonWriter will became easy to write.
Something like:
list.map {
case (user, address) => user.copy(addresses = address.toSeq)
}
score:5
That should help
import anorm._
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class User(
id: Pk[Long] = NotAssigned,
name: String = "",
email: String = "",
addresses: Seq[Address])
case class Address(
id: Pk[Long] = NotAssigned,
userId: Long,
city: String)
// Play does not provide Format[Pk[A]], so you need to define it
implicit def pkReads[A](implicit r: Reads[Option[A]]): Reads[Pk[A]] = r.map { _.map(Id(_)).getOrElse(NotAssigned) }
implicit def pkWrites[A](implicit w: Writes[Option[A]]): Writes[Pk[A]] = Writes(id => w.writes(id.toOption))
implicit val addrFormat = Json.format[Address]
implicit val userFormat = Json.format[User]
Now you can easily serialize a user:
val as = Seq(Address(Id(2), 1, "biim"))
val u = User(Id(1), "jto", "jto@foo.bar", as)
scala> Json.toJson(u)
res6: play.api.libs.json.JsValue = {"id":1,"name":"jto","email":"jto@foo.bar","addresses":[{"id":2,"userId":1,"city":"biim"}]}
As Julien says, you can't just serialize a Map[User, Seq[Address]]
. It just does not make sense since User can't be a key in a Json Object.
Source: stackoverflow.com
Related Query
- play scala json of map with list
- Not able to parse Map with Enum to Json in Play Scala
- unable to convert scala map to json with play 2
- How to load JSON file using Play with Scala
- How to convert casbah mongodb list to json in scala / play
- How to transpose a map with list values in Scala
- Functional way to map over a list with an accumulator in Scala
- Converting a Heterogeneous List to and from Json in Play for Scala
- How to parse json list or array in scala for play framework 2.2
- Format nullable Seq or List of objects with Play Json and Salat
- Scala Compiler (2.11.7) anomaly with Play JSON Writes
- Serialize objects with Play Scala api and Json
- Scala - map function to replace negatives with previous number in list
- Scala flatten a map with list as key and string as value
- Scala play JSON mapping doesn't work with inheritance
- Filter list with two criteria and create a map scala
- Convert list to a map with key being an index in Scala
- Scala Implicit Value Behavior with List and Map "Lookups"
- How to update each field in a list using Play json in Scala
- Scala - parse JSON data from API with ScalaJson Play Framework
- Serialize set to json with a custom Writes in Scala Play 2.4
- Play Framework 2.2.2 Scala JSON reads with undefined/null elements causing NoSuchElementException
- play framework working with json objects in Scala
- Scala append Seq in with a string in a List Map or Foreach
- Returning future list in Play for Scala json
- How to map multiple Futures and pass them as arguments to a view using Play with Scala
- Scala List to Map with Next and Previous values
- Scala convert from list to map by property with sum logic
- Parse JSON with map of list
- Parsing HTTP request JSON body in scala with play
More Query from same tag
- How to pass an implicit argument indirectly
- Mismatch between call-by-name parameter and function type
- ScalikeJDBC, raw SQL failing to map or return a valid result set
- case when [RollOverStatus] = 'Y' then 'Yes' Else 'No' end as RollOverStatus how to write in spark-scala 2.4.0
- Why does usage of Option.get gives a compile error
- Generics and Constrained Polymorphism versus Subtyping
- Issue while reading a csv file through Spark
- Fail when tried to run rocket emulator
- Aggregate on multiple columns in spark dataframe (all combination)
- Failed to find data source: ignite
- Min/max with Option[T] for possibly empty Seq?
- How to pass return value of a method as a input to other method
- Logic operators for non-Boolean types in Scala
- Preventing the creation of anonymous classes from traits, without an enclosing object
- NoClassDefFoundError with sbt and scala.swing
- How to convert a dataframe or RDD to a List of Tuples?
- How should an ask timeout be handled by the askee? Is it even possible?
- How to start Play application before tests and then shut it down in specs2?
- How to implement 'Private Chat' module using akka, scala, websockets in play framework?
- How to use TypeSafe config with Apache Spark?
- Pattern matching syntax in Scala/Unfiltered
- scala lift json: pattern match on unknown data?
- Scala - finding first position in which two Seq differ
- comparing Scala lists with Java lists
- scala with xsl-fo: Aligning decimasl in table column
- How to return a List[User] when using sql with slick
- Group and aggregate dataset in spark scala without using spark.sql()
- How to use the values of TaskKey and SettingKey to define setting?
- Scala: wake up sleeping thread
- Currying Functions in Scala