Reading and Writing in Scala Playing Back Lists of Custom Classes

So I have two classes in my project

case class Item(id: Int, name: String)

and

case class Order(id: Int, items: List[Item])

I try to read and write properties for Order, but I get a compiler error:

"Unapply or unapplySeq function not found"

In my controller, I have the following:

implicit val itemReads = Json.reads[Item]
implicit val itemWrites = Json.writes[Item]
implicit val listItemReads = Json.reads[List[Item]]
implicit val listItemWrites = Json.writes[List[Item]]

The code works for itemReadsand itemWrites, but not for the bottom two. Can someone tell me where I'm wrong, I'm new to the Play platform.

Thank you for your time.

+4
source share
3 answers

The error " No unapply or unapplySeq function found" is caused by these two:

implicit val listItemReads = Json.reads[List[Item]]
implicit val listItemWrites = Json.writes[List[Item]]

Just throw them away. As Ende said , Play knows how to deal with lists.

Reads Writes Order ! , Format, Reads Writes, :

case class Item(id: Int, name: String)

object Item {
  implicit val format = Json.format[Item]
}

case class Order(id: Int, items: List[Item])

object Order {
  implicit val format = Json.format[Order]
}

; Item, - Order.

, , . , , - .

+5

, , :

scala> import play.api.libs.json._ 
import play.api.libs.json._

scala>   case class Item(id: Int, name: String)
defined class Item

scala>   case class Order(id: Int, items: List[Item])
defined class Order

scala>   implicit val itemReads = Json.reads[Item]
itemReads: play.api.libs.json.Reads[Item] = play.api.libs.json.Reads$$anon$8@478fdbc9

scala>   implicit val itemWrites = Json.writes[Item]
itemWrites: play.api.libs.json.OWrites[Item] = play.api.libs.json.OWrites$$anon$2@26de09b8

scala>   Json.toJson(List(Item(1, ""), Item(2, "")))
res0: play.api.libs.json.JsValue = [{"id":1,"name":""},{"id":2,"name":""}]

scala>   Json.toJson(Order(10, List(Item(1, ""), Item(2, ""))))
res1: play.api.libs.json.JsValue = {"id":10,"items":[{"id":1,"name":""},{"id":2,"name":""}]}

, - , unapply / List . play-json .

+5

It works:

case class Item(id: Int, name: String)

case class Order(id: Int, items: List[Item])

implicit val itemFormat = Json.format[Item]
implicit val orderFormat: Format[Order] = (
  (JsPath \ "id").format[Int] and
    (JsPath \ "items").format[JsArray].inmap(
      (v: JsArray) => v.value.map(v => v.as[Item]).toList,
      (l: List[Item]) => JsArray(l.map(item => Json.toJson(item)))
    )
  )(Order.apply, unlift(Order.unapply))

It also allows you to configure naming for your JSON object. The following is an example of serialization in action.

Json.toJson(Order(1, List(Item(2, "Item 2"))))
res0: play.api.libs.json.JsValue = {"id":1,"items":[{"id":2,"name":"Item 2"}]}

Json.parse(
  """
    |{"id":1,"items":[{"id":2,"name":"Item 2"}]}
  """.stripMargin).as[Order]
res1: Order = Order(1,List(Item(2,Item 2)))

I would also recommend using formatinstead readand writeif you are doing symmetric serialization / deserialization.

+1
source

Source: https://habr.com/ru/post/1621471/


All Articles