1

This is probably an easy one and my difficulty is likely caused by my newness to Scala (which already is fast becoming my favourite language).

Basically I have some JSON that looks like this:

{
"to"      : "Peter",
"from"    : "Dave",
"bundle"  : [
             {"data": [1,2,3,4,5]},
             {"data": [2,3,4,5,6]}
            ]

}

Now, I've parsed this JSON to the point where I can pull the data from the header (to and from) and can look over the individual messages in the bundle. At the moment I'm using this:

val messages = parsedJSON \\ "bundle" \\ classOf[JObject]

for (m <- messages) println(m)

Which gives me:

Map(data -> List(1, 2, 3, 4, 5))
Map(data -> List(2, 3, 4, 5, 6))

But what I want to do in that loop is take each Map and convert it back to JSON i.e.:

{
"data": [1,2,3,4,5]
}

I've tried render(m) and various other semi-random things to try and get it to work but so far no dice. The closest I've come gives me this error:

No implicit view available from Any => net.liftweb.json.package.JValue.

Can anyone please point me in the right direction?

Thanks in advance!

PeterM
  • 2,534
  • 6
  • 31
  • 38

2 Answers2

3

I think the easiest way to handle this is to create a case class for a bundle. Lift-json can then nicely extract the data into instances. Then you can just loop through them and turn them back into JObjects implicitly by creating 2-tuples.

case class Bundle(data: List[BigInt])

val bundles = (parsedJSON \\ "bundle").extract[List[Bundle]]
// List(Bundle(List(1, 2, 3, 4, 5)), Bundle(List(2, 3, 4, 5, 6)))
bundles
  .map{ bundle => ("data" -> bundle.data)}
  .foreach{ j => println(compact(render(j)))}
//{"data":[1,2,3,4,5]}
//{"data":[2,3,4,5,6]}
Dan Simon
  • 12,891
  • 3
  • 49
  • 55
  • Unfortunately the content of the individual messages in the bundle can be any valid JSON and I won't know what in advance. At the moment I just need to persist the data in each message to a database but to do that easily, I first need to get the message as simple Scala (i.e. Maps and lists) so that it can be handed over to the database for storage... – PeterM Jan 05 '12 at 08:10
  • Is the re-rendered JSON going to the database, or do you need it parsed as scala lists and maps to go to the database? If you don't actually need the lists/maps, you can bypass that whole process and work with the JValues directly. – Dan Simon Jan 05 '12 at 16:30
  • in the end I just used it "as is", but it's a pity that access the data is so fiddly :) – PeterM Jan 06 '12 at 08:58
  • I get on render "recursive method render needs result type" any idea? – User May 25 '13 at 19:59
1

if messages can be any data you can extract those as JValues.

import net.liftweb.json._
import net.liftweb.json.JsonDSL._

val parsedJSON = parse(...)
val bundles = (parsedJSON \\ "bundle").extract[List[JValue]]
compact(render(bundles))
Joni
  • 2,779
  • 23
  • 17