A TypeScript application sends a Uint8Array object through an HTTP POST request to a Scala Play application.
How to convert the Uint8Array object into a Scala object in the Play application?
For example, the TypeScript code sends the following object:
{stuff: new Uint8Array([0, 1, 2])}
Inside the Scala Play controller:
case class StuffData(stuff: List[Byte])
implicit val reads: Reads[StuffData] = Json.reads[StuffData]
def processStuff = Action.async(parse.json[StuffData]) { request =>
val stuffData = request.body
println(stuffData)
}
This does not work... the error message from Play is:
For request 'POST /send-stuff'
[Json validation error List((obj.key,List(JsonValidationError(List(error.expected.jsarray),WrappedArray()))))]
UPDATE:
To be able to get on the Scala side exactly the same byte array as was on the JavaScript side (i.e. a byte for a byte, in the original order), the current code in the accepted answer should be updated to something like:
implicit val stuffReader = new Reads[StuffData] {
def reads(js: JsValue): JsResult[StuffData] = {
JsSuccess(StuffData(
(js \ "stuff").as[Map[String, Int]].toList.sortBy(_._1.toInt).map(_._2.toByte)
))
}
}
Now, the reader populates a
case class StuffData(stuff: List[Byte])
with the same order as the original JavaScript Uint8Array.
It's possible to convert all the Ints into Bytes without losing information, because we know that all the Ints are in the range [0..255].