1

I am trying to parse a Travis-ci api response which has the following structure :

{
    repos: [
          {"id": ..., "slug": ...}, 
          {"id": ..., "slug": ...}, 
          {"id": ..., "slug": ...}
    ]
}

So I have decided to create case classes reflecting the json structure :

case class TravisRepository(id: String, slug: String)
case class TravisUserRepositories(repos: Seq[TravisRepository])

And I have added the implicit Read methods :

implicit val travisRepositoryReads: Reads[TravisRepository] = (
    (JsPath \ "id").read[String] and
    (JsPath \ "slug").read[String]
)(TravisRepository.apply _)

implicit val travisUserRepositoriesReads: Reads[TravisUserRepositories] = (
    (JsPath \ "repos").read[Seq[TravisReposity]]
)(TravisUserRepositories.apply _)

However the second read is not compiling with the following error :

Overloaded method value [read] cannot be applied to (Seq[utils.TravisRepository] => utils.TravisUserRepositories)

When adding another column to the second Read, this compiles. With a single column, this is not compiling anymore. Can someone explain why is this not compiling? Is it a limitation of the Play-Json parser?

i.am.michiel
  • 10,063
  • 7
  • 46
  • 85

1 Answers1

2

That's simply because you have the case "only one single field in your case class"... To be able to use the Functional combining, you need at least 2 fields.

// would be OK implicit val travisUserRepositoriesReads: Reads[TravisUserRepositories] = ( (JsPath \ "repos").read[Seq[TravisReposity]] and ... )(TravisUserRepositories.apply _)

// should be OK implicit val travisUserRepositoriesReads: Reads[TravisUserRepositories] = ( (JsPath \ "repos").read[Seq[TravisReposity]] map (TravisUserRepositories.apply _)

mandubian
  • 4,427
  • 1
  • 20
  • 15
  • Indeed, just found : http://stackoverflow.com/questions/14754092/how-to-turn-json-to-case-class-when-case-class-has-only-one-field. Thanks a lot. – i.am.michiel May 12 '14 at 09:52