10

This JSON automated mapping example from the play documentation fails. why? https://www.playframework.com/documentation/2.5.x/ScalaJsonAutomated

libraryDependencies += "com.typesafe.play" %% "play" % "2.5.0"
---
import play.api.libs.json._
case class Resident(name: String, age: Int, role: Option[String])
implicit val residentWrites = Json.writes[Resident]
println(Json.toJson(Resident("john", 33, None)))
---
Error: No unapply or unapplySeq function found
      implicit val residentWrites = Json.writes[Resident]
David Portabella
  • 12,390
  • 27
  • 101
  • 182
  • For me it simply doesn't fail. I open amm repl, get dependency via `load.ivy("com.typesafe.play" %% "play" % "2.5.0")` and paste your 4 lines of code getting `{"name":"john","age":33}`. This error usually happens when your `class` is not a `case class`, but everything is fine here. – Łukasz Apr 29 '16 at 07:39
  • wow, I didn't know about Ammonite! It looks great, i'll try this now – David Portabella Apr 29 '16 at 12:06
  • yes, it works also for me from the amm repl. :O I'll check again my project – David Portabella Apr 29 '16 at 12:12
  • so, it works on amm repl. however i've created a minimal sbt project and i still get the error, in the same computer (OSX 10.10.5) :O could you please checkout this project and test it? https://github.com/dportabella/test – David Portabella Apr 29 '16 at 13:21
  • 4
    The issue is you declare your class inside a method, I can't explain why this doesn't work but moving case class out of main method, up into the `object Test` or to a file level makes this compile. – Łukasz Apr 29 '16 at 13:34
  • I see, thanks. feel free to post this as an answer so that i can accept it. – David Portabella Apr 29 '16 at 23:42
  • FYI this can also happen if your case class has more than 22 fields. In such case, you can use following library: https://github.com/xdotai/play-json-extensions – Gaël J Mar 30 '21 at 15:16

3 Answers3

13

The problematic code looked more or less like that:

import play.api.libs.json._

object Test {
  def main(args: Array[String]): Unit = {
    case class Resident(name: String, age: Int, role: Option[String])
    implicit val residentWrites = Json.writes[Resident]
    println(Json.toJson(Resident("john", 33, None)))
  }
}

The issue here was that this macro apparently doesn't work for classes defined inside methods. This is not a troubling limitation though as we rather don't do this sort of things.

To resolve issue class def can be moved somewhere else, like object level

object Test {
  case class Resident(name: String, age: Int, role: Option[String])

  def main(args: Array[String]): Unit = {
    implicit val residentWrites = Json.writes[Resident]
    println(Json.toJson(Resident("john", 33, None)))
  }
}

or file level

case class Resident(name: String, age: Int, role: Option[String])

object Test {
  def main(args: Array[String]): Unit = {
    implicit val residentWrites = Json.writes[Resident]
    println(Json.toJson(Resident("john", 33, None)))
  }
}

I understand that this was only for test purposes to see minimal example, but I will still mention how we usually define classes with Writes.

object Resident {
  implicit val residentWrites = Json.writes[Resident]
}

case class Resident(name: String, age: Int, role: Option[String])

This way, whenever you import the Resident, its writes will be in the implicit scope.

Łukasz
  • 8,555
  • 2
  • 28
  • 51
8

I got here through a google search.

For me was a case class that had more than 22 attributes that resulted in the same No unapply or unapplySeq function found error

Hope it helps someone else

Ismail H
  • 4,226
  • 2
  • 38
  • 61
0

try using jsonx

object Resident {
  implicit val format = Jsonx.formatCaseClass[Resident]
}
Skully
  • 2,882
  • 3
  • 20
  • 31
  • 2
    Welcome to Stack Overflow! Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you edit your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Skully Jan 02 '23 at 02:11