3

Given the following Json array:

{
    "success": true,
    "data": [
        {
            "id": 594,
            "stage_id": 15,
            "title": "test deal",
            "value": 0,
            "currency": "EUR",
            "add_time": "2014-03-18 17:45:51",
            "update_time": "2014-03-24 13:30:27",
            "stage_change_time": "2014-03-24 13:30:27",
            "active": true,
            "deleted": false,
            "status": "open",
            "expected_close_date": null,
            "stage_order_nr": 1,
            "person_name": "test"
        },
        {
            "id": 601,
            "stage_id": 15,
            "title": "test deal2 deal",
            "value": 0,
            "currency": "EUR",
            "add_time": "2014-03-24 14:11:00",
            "update_time": "2014-03-24 14:11:00",
            "stage_change_time": "2014-03-24 14:11:00",
            "active": true,
            "deleted": false,
            "status": "open",
            "expected_close_date": null,
            "stage_order_nr": 1,
            "person_name": "test deal2"
        }
    ],
    "additional_data": {
        "pagination": {
            "start": 0,
            "limit": 100,
            "more_items_in_collection": false
        }
    }
}

I want to get a List of deals out of it and I am trying it like so

case class Deal(id: Long, stage_id: Long)

  def getAllDeals(): List [Deal] = {

    var holder : WSRequestHolder = WS.url(PipeDriveApiBaseUrl + "/deals")

    val complexHolder: WSRequestHolder = holder.withQueryString("filter_id" -> "9", "api_token" -> SalesManagerApiKey)
    val futureResponse: Future[Response] = complexHolder.get()

    implicit val dealReader = Json.reads[List[Deal]]

    val futureJson: Future[List[Deal]] = futureResponse.map(
      response => (response.json \ "data").validate[List[Deal]].get
    )

I get the exception No unapply function found which is related to the implicit reads value. But commenting it out, I will get No Json deserializer found for type List[models.Deal]. Try to implement an implicit Reads or Format for this type.

I couldn't solve the problem with these answers here and here. What do I miss or misunderstand?

Community
  • 1
  • 1
Steven
  • 1,218
  • 3
  • 18
  • 38
  • 3
    Did you try making a `Json.reads` for `Deal` instead of `List[Deal]`? Like this: `implicit val dealReader = Json.reads[Deal]` – Carsten Mar 25 '14 at 12:46
  • 2
    Also, if you're going to use `.validate[List[Deal]].get`, you may as well just use `.as[List[Deal]]` since you're throwing out the benefit of using `JsResult` with that `.get` call. – Ryan Mar 25 '14 at 14:35
  • @Carsten Using `Deal` instead of `List[Deal]` worked! Thanks so much. I thought, I tried this before... – Steven Mar 26 '14 at 12:42
  • @Ryan I considered your advice. Thanks! – Steven Mar 26 '14 at 12:43

1 Answers1

4

Instead of defining an implicit Json.reads for List[Deal], create one for Deal:

implicit val dealReader = Json.reads[Deal]

Play already has a built-in implicit JSON reads converter for Lists. Actually, it has one for all Traversables. You can look at the code, but it's a bit hard to read. The thing is: Play can convert JSON lists to List objects. What it doesn't know is how to read/convert a Deal, and that's why you need the implicit definition mentioned above.

Carsten
  • 17,991
  • 4
  • 48
  • 53