Question

To begin with I would like to say sorry for long post, and I really appreciate those who still look into my problem.

I have a controller that should return a json-response with a structure like:

{
   result: [
       {
           key: value,
           key: value,
           key: value,
           key: [
              {
                 key: value,
                 key: value,
                 key: value
              },...
           ]
       },....
   ]
}

However I have problems getting the Writes to work as I want.

Note. I will add comments under the line where I have problem.

object APIController extends Controller {

  def feed() = Action {
    val objects = repo.getObjects().toList
    Ok(Json.toJson(Json.obj("result" -> Class_1.apply(objects).result)))
  }

first off, if I don't make a Json.obj("result" -> List[objects]) the result key isn't shown in the JSON-result. If I add a Writer for that I get errors saying that the List[objects] must have a Writer. But if I write it like above it doesn't need a Writer for the List[objects]

  case class Class_1 (result: Seq[Class_2])
  object Class_1 {
    def apply(objs: List[Object]) = {
      var result:ListBuffer[Class_2] = ListBuffer[Class_2]()
      for(obj <- objs) feedResult += Class_2.apply(code)
      new Class_1(result.toList)
    }
   }

*this is where I would put the Writer for Class_1. But if I do this like implicit val class1Writer = new Writes[Class_1] { override def writes(o: Class_1): JsValue = Json.obj("result" -> o.result) } I get the problems I mentioned earlier, that I suddenly need a Writes for a List[objects] of that type*

  case class Class_2 (id: Long, id2: Long, listOfStuff: Seq[Class_3])
  object Class_2 {
    def apply(obj: Object) = {
      var items: ListBuffer[Class_3] = ListBuffer[Class_3]()
      for(obj1 <- obj.getListOfStuff()) items += Class_3.apply(obj1)
      new Class_2(obj.firstID, obj.secID, items.toList)
    }
  }
  implicit val class2Writes = new Writes[Class_2] {
    override def writes(o: Class_2): JsValue = {
      Json.obj(
        "id" -> o.id,
        "id2" -> o.id2,
        "items" -> o.listOfStuff
      )
    }
  }

*the "items" -> o.listOfStuff says it needs a Writes for a List[types in the list] but I have a Writes for the objects in the list (Class_3) and I don't need a Writes for when serializing a list of objects from Class_2, why is it behaving like this?*

  case class Class_3 (id: Long, text: String)
  object Class_3 {
    def apply(obj: Object) = {
      new Class_3(obj.id, obj.funnyText)
    }
  }
  implicit val class3Writer = new Writes[Class_3] {
    override def writes(o: Class_3): JsValue = {
      Json.obj(
        "id" -> o.id,
        "text" -> o.text
      )
    }
   }
}

The error I get from this code is:

No Json deserializer found for type Seq[Class_3]. Try to implement an implicit Writes or Format for this type.
[error]         "items" -> o.listOfStuff
[error]                             ^

If I remove this line in the Writes it compiles and works. And I think that's weird since the first list I serialize doesn't have a Writer, only for the objects in the list.

Does anyone know why it behaves like this? What should I do to accomplish what I'm after? (I hope you see what I'm trying to do)

Thanks in advance.

Was it helpful?

Solution

Just put the implicit val class3Writer ahead of class2Writes

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top