What does it mean the JsValue*

In spray.json, there is this object:

object JsArray {
  val empty = JsArray(Vector.empty)
  def apply(elements: JsValue*) = new JsArray(elements.toVector)
  @deprecated("Use JsArray(Vector[JsValue]) instead", "1.3.0")
  def apply(elements: List[JsValue]) = new JsArray(elements.toVector)
}

What does it mean in the JsValue* in the apply argument the *?

Also, I’m trying to parse a json map and the compilation gives me this error:

error] /Users/imetallica/Documents/Projects/compensations/src/main/scala/com/paggi/accounting/core/Entities.scala:56: value Map is not a case class, nor does it have an unapply/unapplySeq member
[error]         case JsObject(Map(("id", JsString(id)), ("flat", JsNumber(flat)), ("fee", JsNumber(fee)))) =>
[error]                       ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 1 s, completed 19/09/2017 11:35:24

I’m trying to figure out why. Can someone shed a light? :slight_smile:

The * in JsValue* means it’s a varargs parameter. It means you can call apply with zero or more JsValue arguments. elements will be a Seq[JsValue].

That error says that you can’t use Map in a pattern matching expression.

1 Like

For anyone with has the same problem and, for future reference, the solution is:

       json match {
        case JsObject(intermediary) =>
          val it =
            for {
              JsString(id) <- intermediary.get("id")
              JsNumber(fee) <- intermediary.get("fee")
              JsNumber(flat) <- intermediary.get("flat")
            } yield Intermediary(UUID.fromString(id), flat.bigDecimal, fee.bigDecimal)
          it.getOrElse(throw DeserializationException(s"Cannot parse intermediary: $it."))
        case a => throw DeserializationException(s"Cannot parse intermediary: $a.")
      }

I guess you can pattern match on the fields as a Seq like this

json match {
  case JsObject(Seq(JsString(id), JsNumber(flat), JsNumber(Fee))) => 
    Intermediary(UUID.fromString(id), flat.bogDecimal, fee.bigDecimal)
  case a => throw DeserializationException(...)
}

The implicit assumption here is that the json fields must be in this specific order.

I didn’t test the code, so let me know if it works as is.