2

I'm a bit confused why the code below doesn't work:

  implicit val connectReads: Reads[ConnectCommand] = (
    (JsPath \ "uuid").read[String]
    )(ConnectCommand.apply _)

  private def generateMessage[T](json: JsValue) = json.validate[T] match {
    case s: JsSuccess[T] => s.asOpt
    case e: JsError => None
  }

The function would be called as follows:

generateMessage[ConnectCommand](json)

I'm getting the following errors:

Error:(59, 64) No Json deserializer found for type T. Try to implement an implicit Reads or Format for this type.
  private def generateMessage[T](json: JsValue) = json.validate[T] match {
                                                               ^
Error:(59, 64) not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])play.api.libs.json.JsResult[T].
Unspecified value parameter rds.
  private def generateMessage[T](json: JsValue) = json.validate[T] match {
                                                           ^

I'm fairly new to Scala generics... is there any way to do what I'm trying to do here?

3
  • 1
    'Scala for the Impatient' by Cay S. Horstman has a good chapter on implicits, but it might be difficult to just jump into it without reading some of the earlier chapters. Commented Jun 11, 2015 at 0:50
  • Thanks for the tip! I've actually read half of that book... it's great. I guess it's time to read the second half! Commented Jun 11, 2015 at 0:51
  • 1
    I found it extremely useful to do the exercises - and some took a lot of time and got really difficult in the later chapters. There is a complete and generally high quality set of solutions at github.com/BasileDuPlessis/scala-for-the-impatient. It is best to develop your own solution first and then see how Basile did it to possibly learn another approach. Commented Jun 11, 2015 at 0:56

2 Answers 2

3

According to the documentation JsValue.validate requires an implicit Reads for your type to be available:

def validate[T](implicit rds: Reads[T]): JsResult[T] 

Assuming you have it available at the place you are calling generateMessage from, you have to pass it into generateMessage, so that validate would see it as well:

private def generateMessage[T](json: JsValue)(implicit rds: Reads[T])

or the shorter form:

private def generateMessage[T : Reads](json: JsValue)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply... how would generateMessage then be called?
@threejeez Nothing else changes, if you have the appropriate implicit Reads available when you call generateMessage.
1

This is not really related to generics, but rather implicits and how libraries require you to define implicits types and import them.

This is required because the validate function does not know the format of your JsValue, therefore requires the implicit scope to provide one. It then uses the format to validate it. It is confusing at first but eventually is nicer because you don't have to explicitly provide the format for every method call when a JSON format is required.

Also these are the two lines that give it away in the error message:

Try to implement an implicit Reads or Format for this type.

not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])

We see that you either need to import the implicit Format/Reads or define one yourself. You can read up on how to do this in the relevant section of the Play! documentation.

EDIT:

Your method is missing the implicit parameter (implicit reads: Reads[T]) to pass it on to the validate function:

private def generateMessage[T](json: JsValue)(implicit reads: Reads[T]) = json.validate[T] match {
 case s: JsSuccess[T] => s.asOpt
 case e: JsError => None
}

1 Comment

Thanks for your reply. I've actually done that directly above my function. I've edited my question to show it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.