Monday, November 1, 2010

Scala & Json (Lift-web): Trouble with "mapping" field name to another name

This is a trivial mistake that just ate up the last 2 hours of my life that I will never get back again.

One thing that is important is to be able to take the "raw" parsed json object and rename some of the fields since GoGrid uses some names that are reserved and/or have other Scala meanings.  For example, GoGrid uses Object and Option to mean things specific to their environment.  

This is possible by using the JValue's map function to postprocess AST.  Following the example in the readme documenation, I reproduced the following:
package org.gogrid.sandbox
abstract class jsonSandbox
{ }

case class Person(firstname: String)

And then started up the Scala interpreter:
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import org.gogrid.sandbox._

scala> import net.liftweb.json.JsonParser._
import net.liftweb.json.JsonParser._

scala> implicit val formats = net.liftweb.json.DefaultFormats 
formats: net.liftweb.json.DefaultFormats.type = net.liftweb.json.DefaultFormats$@1c9fe7e

scala> val jsonString = """ { "first-name" : "Jim" } """
jsonString: java.lang.String =  { "first-name" : "Jim" } 

scala> val json = parse(jsonString)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(first-name,JString(Jim))))

scala> json map {
     | case JField("first-name", x) => JField("firstname", x)
     | case x => x
     | }
<console>:16: error: not found: value JField
       case JField("first-name", x) => JField("firstname", x)
            ^

Heh? Why is JField not found???

My "Oh DUH moment":

I did NOT import the package where things like JField, JArray are defined.
 
Insert wall bash here.
scala> import net.liftweb.json.JsonAST._
import net.liftweb.json.JsonAST._

scala> json map {
     | case JField("first-name", x) => JField("firstname", x)
     | case x => x
     | }
res4: net.liftweb.json.JsonAST.JValue = JObject(List(JField(firstname,JString(Jim))))

Dang it.

No comments:

Post a Comment