Reputation: 187
I am trying to make somethink like that:
case class Obj(name: String, list: List[Integer], isPossible: Boolean) {
override def apply(name: String, list: List[Integer]): Obj = {
Obj(name, list, list.exists((x: Integer) => x >= 10 && x <= 100))
}
}
implicit val objReads: Reads[Obj] = (
(__ \ "name").read[String] and
(__ \ "list").read[List[Integer]]
)(Book.apply _)
but it doesn't compile, it returns me a error:
Overloaded method value [apply] cannot be applied to ((String, List[Integer], Boolean) => models.Api.Obj)
is it possible to do this, or just i have to have the same amount of fields in case class and in read combinator, and this is not possible
Upvotes: 2
Views: 742
Reputation: 55569
There are a few problems here. First, the apply
method for a case class is defined within it's companion object, not the case class itself. The second problem is that once you define the apply
method within the companion object, it's going to cause an ambiguous reference error in Obj.apply _
. This is because your declaration of apply
is an overload, and not an override, since the signatures do not match.
One way to solve this would be to remove isPossible
from the constructor of Obj
, and instead make it a method or val. You would still be able to access it the same way.
case class Obj(name: String, list: List[Int]) {
val isPossible: Boolean = list.exists((x: Int) => x >= 10 && x <= 100)
}
object Obj {
implicit val objReads: Reads[Obj] = (
(__ \ "name").read[String] and
(__ \ "list").read[List[Int]]
)(Obj.apply _)
}
The only problem this poses is that isPossible
would no longer be included in JSON writes, which can be fixed like so:
implicit val objWrites: Writes[Obj] = (
(__ \ "name").write[String] and
(__ \ "list").write[List[Int]] and
(__ \ "isPossible").write[Boolean]
)( obj => (obj.name, obj.list, obj.isPossible) )
Alternatively, you could rename the overloaded apply
to something else, and use that for Reads
instead of Obj.apply
. However, I think keeping isPossible
as a val
is better, because it's calculation would be done on object creation, and not when being passed to the constructor. This would ensure that you could not just call Obj("test", List(1), true)
with an invalid state for isPossible
.
Upvotes: 2