2

I need to create a json object, i use play-json lib for Scala.

I have this code:

import play.api.libs.json
import play.api.libs.json._

object Start {
    def main(args: Array[String])
    {
        val GraphDbJson= Json.obj("name"->"father","nodeid"->1,"children"->Json.arr(func1))
        println(Json.prettyPrint(GraphDbJson))
    }

    def func1():JsValue=
    {
        var JObjChildrenNodes=Seq[JsValue]()

        JObjChildrenNodes :+ Json.obj("name"->"child1","nodeid"->2,"children"->Json.arr())
        JObjChildrenNodes :+ Json.obj("name"->"child2","nodeid"->3,"children"->Json.arr())     
        Json.toJson(JObjChildrenNodes)
    }
}

and the output is:

{
    "name" : "father",
    "nodeid" : 1,
    "children" : [ [ ] ]
}

how can I pass an json array ? Why the return value of func1 is empty?

Thank you in advance

faster2b
  • 662
  • 6
  • 22
  • I did create that in this link, used the or [Create nested Json][1] [1]: http://stackoverflow.com/a/21377682/1820466 – Fred Ondieki Jan 27 '14 at 13:38

1 Answers1

2

You should replace :+ with +:= (since the default implementation of Seq is List you should not use :+=).

Seq is immutable. With :+ you are creating a new Seq.

So you should use nodes = nodes :+ Json.obj(...) instead of nodes :+ Json.obj(...), or just nodes :+= Json.obj(...) (see the last part of this answer).

You could use mutable collection like mutable.Seq with += operation: nodes += Json.obj(...).

I would prefer to create a collection this way:

nodes = Seq(
  Json.obj(...),
  Json.obj(...)
)

Note that default implementation of Seq is List and append (:+) operation on List is very inefficient - you should use prepend - +: and +:=.

Alternative solution: there is Json.writes (and Json.reads) in Play, so you could create a class and convert it to JSON this way:

case class MyNode(name: String, nodeid: Int, children: Seq[MyNode] = Nil)
implicit lazy val myNodeWrites = Json.writes[MyNode]

val myNode = MyNode("father", 1, MyNode("child1", 2) :: MyNode("child2", 3) :: Nil)
val graphDbJson = Json.toJson(myNode)
Json.prettyPrint(graphDbJson)
// {
//   "name" : "father",
//   "nodeid" : 1,
//   "children" : [ {
//     "name" : "child1",
//     "nodeid" : 2,
//     "children" : [ ]
//   }, {
//     "name" : "child2",
//     "nodeid" : 3,
//     "children" : [ ]
//   } ]
// }

Also: there is a error in your code: you should replace Json.arr(func1) with func1: Json.arr(func1) creates an array of arrays, since func1 already returns a json array.

Community
  • 1
  • 1
senia
  • 37,745
  • 4
  • 88
  • 129
  • @faster2b: Note that you don't have to work with `Json.obj` - see update in my answer. – senia Dec 28 '13 at 17:46
  • @faster2b: you should remove `Json.arr`, see update in my answer. – senia Dec 28 '13 at 17:53
  • @faster2b: I've just tested `case class` code - works fine. Result: `{"name":"father","nodeid":1,"children":[{"name":"child1","nodeid":2,"children":[]},{"name":"child2","nodeid":3,"children":[]}]}` – senia Dec 28 '13 at 18:27