//Item.scala
package model
trait Item {val id: String}
class MItem(override val id: String, val name: String) extends Item
class DItem(override val id: String, override val name: String, val name2: String)
extends MItem(valid, name, name2)
object ItemWrites {
implicit val MItemWrites = new Writes[MItem] {
def writes(dItem: MItem) = Json.obj(
"id" -> mItem.id,
"name" -> mItem.name
)
}
implicit val DItemWrites = new Writes[DItem] {
def writes(dItem: DItem) = Json.obj(
"id" -> dItem.id,
"name" -> dItem.name,
"name2" -> dItem.name2
)
}
}
//Response.scala
package model
import ItemWrites.MItemWrites
import ItemWRites.DItemWrites
trait Response {
val title : String,
val items : Seq[Item],
}
case class MResponse(title: String, items: Seq[MItem]) extends Response
case class DResponse(title: String, items: Seq[DItem]) extends Response
object ResponseWrites {
implicit val mResponseWrite = new Writes[MResponse] {
def writes(mResponse: MResponse) = Json.obj(
"title" -> mResponse.title,
"items" -> mResponse.items
)
}
implicit val dResponseWrite = new Writes[DResponse] {
def writes(dResponse: DResponse) = Json.obj(
"title" -> dResponse.title,
"items" -> dResponse.items // **compile time error**
)
}
}
I get compile time error on line dResponse.items.
> [error] Note: implicit value dtcTopicPageResponseWrite is not
> applicable here because it comes after the application point and it
> lacks an explicit result type
> [error] "items" -> dResponse.items
Seems that this is happening as DItem inherits form MItem and the compile is getting confused between subclass and super class. How do i get around this.
I was able to get your code compiling in Scala 2.11, Play 2.5.x by explicitly stating the types of the Writes
you've declared in ItemWrites
- namely:
object ItemWrites {
implicit val MItemWrites:Writes[MItem] = new Writes[MItem] {
def writes(mItem: MItem) = Json.obj(
"id" -> mItem.id,
"name" -> mItem.name
)
}
implicit val DItemWrites:Writes[DItem] = new Writes[DItem] {
def writes(dItem: DItem) = Json.obj(
"id" -> dItem.id,
"name" -> dItem.name,
"name2" -> dItem.name2
)
}
}
Once I did that, Scala was able to find out which implicit was right and away it went.
You should explicitly set which Writer[T] is going to be used because they use inheritance. I didn't test the code below but it should compile and work;
implicit val dResponseWrite = new Writes[DResponse] {
import ItemWrites.DItemWrites
def writes(dResponse: DResponse) = Json.obj(
"title" -> dResponse.title,
"items" -> Json.toJson(dResponse.items) // **compile time error**
)
}
I think it's better for you to have a Writes for the super type Item that will just do match case to check it's type and do toJson. Don't forget to have it implicitly imported
object ItemWrites {
implicit val MItemWrites = new Writes[MItem] {
def writes(dItem: MItem) = Json.obj(
"id" -> mItem.id,
"name" -> mItem.name
)
}
implicit val DItemWrites = new Writes[DItem] {
def writes(dItem: DItem) = Json.obj(
"id" -> dItem.id,
"name" -> dItem.name,
"name2" -> dItem.name2
)
}
implicit val ItemWrites = new Writes[Item] {
def writes(item: Item) = item match {
case i: DItem => i.toJson //code for converting DItem to Json
case i: MItem => i.toJson //code to convert MItem to Json
case _ => throws new RuntimeException("Unsupported Type.")
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.