Kevin Meredith Kevin Meredith - 1 year ago 73
JSON Question

Json#arr w/ List[Int] Input

Looking at this helpful answer on encoding a

in the Play JSON library,

I tried to use Json#arr:

import play.api.libs.json._

scala> Json.arr( 1, 2, 3 )
res21: play.api.libs.json.JsArray = [1,2,3]

All works well so far, but what if I have a

scala> Json.arr( List(1,2,3) )
res22: play.api.libs.json.JsArray = [[1,2,3]] // not what I wanted

I attempted to pass the
as var-args (if that's the right term):

scala> Json.arr( List(1,2,3): _* )
<console>:18: error: type mismatch;
found : List[Int]
required: Seq[play.api.libs.json.Json.JsValueWrapper]
Json.arr( List(1,2,3): _* )

But that did not work.

Then, I tried to create a
, and then pass that, via var-args, to

scala> List(1,2,3).map(Json.toJsFieldJsValueWrapper)
<console>:18: error: No Json serializer found for type T. Try to implement an implicit Writes or Format for this type.

Although that failed, the following works when applied to a single

scala> Json.toJsFieldJsValueWrapper(1)
res27: play.api.libs.json.Json.JsValueWrapper = JsValueWrapperImpl(1)

scala> Json.arr(res27)
res28: play.api.libs.json.JsArray = [1]

How can I pass a
to get an output of
, i.e. a
consisting of three

Answer Source

You could use Json.toJson, validate as a JsArray, or return an empty one if invalid:

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> Json.toJson(list).validate[JsArray].getOrElse(JsArray())
res6: play.api.libs.json.JsArray = [1,2,3]

You could also modify your lambda slightly with Json.arr:

scala> Json.arr( _*)
res10: play.api.libs.json.JsArray = [1,2,3]

It seems as though without the parentheses, the compiler is having trouble inferring what T is. This is because the compiler tries to resolve the implicit before eta-expanding the anonymous function, so it doesn't know what argument will be passed to Json.toJsFieldJsValueWrapper yet. Json.toJsFieldJsValueWrapper(_) is fundamentally different because it expands to a slightly different Function1:

 x => Json.toJsFieldJsValueWrapper(x)

Here the compiler knows that x will be an Int, so the implicit Writes[Int] is resolved.

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