0
votes

My case classes looks like this:

case class Person(personalInfo: PersonalInfo, bankInfo: BankInfo)

case class PersonalInfo(fname: String, lname: String)
case class BankInfo(atmCode: Int, creditCard: CreditCard)
case class CreditCard(number: Int, experationDate: String)

so to be able to get a person in my controller I added serealizer for person:

object PersonSerealizer {

  implicit val PersonalInfoFormat: OFormat[PersonalInfo] = Json.format[PersonalInfo]
  implicit val CreditCardFormat: OFormat[CreditCard] = Json.format[CreditCard]
  implicit val BankInfoFormat: OFormat[BankInfo] = Json.format[BankInfo]
  implicit val PersonFormat: OFormat[Person] = Json.format[Person]

}

in my controller I have a super simple action that looks like this:

i

mport serializers.PersonSerealizer._

def getBrothers(): Action[JsValue] = Action.async(parse.json) { request =>
    request.body.validate[Person] match {
      case JsSuccess(person, _) => 
        brothersService.getBrothers(person) // this returns a List[Person]
        .map(res => Future{Ok(res)})
      case JsError(errors) => Future(BadRequest("Errors! " + errors.mkString))
    }
  }

but I get this error:

Error:(23, 81) No unapply or unapplySeq function found for class BankInfo: / implicit val BankInfoFormat: OFormat[BankInfo] = Json.format[BankInfo]

something is weird...from what I know it supposed to work

1
This means that the problem is with this line somewhere else in your code implicit val RouterInvoiceDataFormat: OFormat[BankInfo] = Json.format[BankInfo] . And has nothing to do with the code which you have shown here. You will need to import the BankInfo serializer in wherever this line is. - sarveshseri

1 Answers

1
votes

The order of defining your implicits seems to matter. Also, I think it is safer to use companion objects instead of defining them inside an arbitrary object.

  case class PersonalInfo(fname: String, lname: String)
  object PersonalInfo {
    implicit val personalInfoJsonFormat = Json.format[PersonalInfo]
  }

  case class CreditCard(number: Int, experationDate: String)
  object CreditCard {
    implicit val creditCardJsonFormat = Json.format[CreditCard]
  }

  case class BankInfo(atmCode: Int, creditCard: CreditCard)
  object BankInfo {
    implicit val bankInfoJsonFormat = Json.format[BankInfo]
  }

  case class Person(personalInfo: PersonalInfo, bankInfo: BankInfo)
  object Person {
    implicit val personJsonFmt = Json.format[Person]
  }

  // Your action will be like this
  def getBrothers() = Action.async(parse.json) { req =>
    req.body.validate[Person] match {
      case JsSuccess(p, _) => 
        Future.successful(Ok(Json.toJson(service.getBrothers(p))))
      case JsError(errors) => 
        Future.successful(BadRequest(JsError.toJson(errors)))
    }
  }