0

I have an issue in Scala I'm really stuck on. I know the title is probably more confusing so let me try to explain it as easy as possible. Imagine I have an abstract class called Repo. This class describes a couple of methods on them, most of them are already implemented. The class Repo looks like this:

abstract class Repo[T](name: String) {

  implicit def collection(implicit db: DefaultDB): JSONCollection =
    db.collection[JSONCollection](name)

  def findOne(selector: JsObject)(implicit collection: JSONCollection): Future[Option[T]] = {
    collection.find(selector).one[T]
  }

  ...

}

A basic implementation of this class would look like this:

import models.Models.Resume._

object ResumeRepo extends Repo[Resume]("resumes")

Now if I try to compile this, it gives me an error, saying: "No Json serializer found for type T. Try to implement an implicit Writes or Format for this type." which is odd because I explicitly include the implicit Format in the ResumeRepo implementation class. Why is this error displaying?

Martijn
  • 2,268
  • 3
  • 25
  • 51
  • Strange that the warning mentions `T` instead of the type resolved as this type parameter at compile-time. – cchantep May 24 '15 at 19:31
  • Well.. where is the implementation of `Format` or `Writes` you say you explicitly have? – Michael Zajac May 24 '15 at 21:00
  • @m-z It's defined in the Resume model. The Resume model is just a case-class and the format is just based on the case-class. Do I need to include it? – Martijn May 24 '15 at 22:27

1 Answers1

1

I guess that one[T] expects an implicit Reads[T] to be accessible at its application site. Which means the implicit is selected in the definition of findOne, in the class Repo, for the generic type T. So you need to make such an implicit visible there.

You have three options. You can add an implicit argument of type Reads[T]

  • to findOne :

    def findOne(selector: JsObject)(implicit collection: JSONCollection, readsT : Reads[T]) : ...
    

    That way the implicit has to be visible when findOne is called.

  • as class implicit argument:

    abstract class Repo[T](name: String)(implicit readsT : Reads[T]) { ...
    

That way it is visible anywhere in Repo but it must be visible at inheriting and instantiating site. For example you can't put the implicit in RepoResume because it has to be visible at object creation.

  • finaly as abstract value member of the abstract class

    abstract class Repo[T](name: String) {
       implicit val readsT : Reads[T]
     ...
    }
    
    object RepoResume extends Repo[Resume]("resume") {
       implicit val readsT : Reads[T] = ....
    }
    
  • Could you also tell me why the `implicit def` of the collection is not working as it should. I just compiled your suggestion and this is also giving me an error now. – Martijn May 25 '15 at 13:18
  • `could not find implicit value for parameter collection: JSONCollection` – Martijn May 28 '15 at 14:50