Giovanni Azua Giovanni Azua -4 years ago 163
Scala Question

Scala-Play Json: How to define a Writes for any Saddle Frame?

I have a Scala-Play web services application that does a bit of computations that generate Saddle frames and need to dump those Saddle frames into Json. So I define a

like this:

object JsonUtils {
implicit def frameWrites[RX, CX, E] = new Writes[Frame[RX, CX, E]] {
override def writes(frame: Frame[RX, CX, E]): JsValue = {
val json: JsArray = Json.arr(
(0 until frame.numRows).map { i =>
Json.obj( ->
(0 until frame.numCols).map { j =>
Json.obj( ->, j).toString

and then attempt to use it like this:

import utils.JsonUtils._

def computingAction = Action {
val pnlStatistics: Frame[String, String, Double] = ???

but then always get the error
Cannot write an instance of org.saddle.Frame[String,String,Double] to HTTP response. Try to define a Writeable[org.saddle.Frame[String,String,Double]]

To be really explicit I have also tried defining as part of

implicit def frameSSDWrites = frameWrites[String, String, Double]

but this one also doesn't get picked up ...

UPDATE invoking the writer explicitly works:


Answer Source

A Play result input must be some content that can be put in a HTTP response.

Your action does not know that you want to write it specifically as JSON, so you need to return Ok(Json.toJson(pnlStatistics)).

Let us see how this work:

  • The type of pnlStatistics is a Frame, so you can serialize it to JSON, using your implicit Writes[Frame], so Json.toJson accepts it as parameter. It then returns a JsValue.

  • Since there is also an implicit Writeable[JsValue] in scope, Ok then accepts this value as content for your response (and will also add the Content-Type header).

If you forget the explicit JSON conversion, Play has no way to determine how you want the frame handled in the response.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download