views:

160

answers:

2

i am confused on how to combine the json library in dispatch and lift to parse my json response.

I am apparently a scala newbie.

I have written this code :

val status = { 
      val httpPackage = http(Status(screenName).timeline) 
      val json1 = httpPackage 
      json1 
    } 

Now i am stuck on how to parse the twitter json response

i tried using the JsonParser and got this error :

val status1 = JsonParser.parse(status) 

:38: error: overloaded method value parse with alternatives: (s: java.io.Reader)net.liftweb.json.JsonAST.JValue (s: String)net.liftweb.json.JsonAST.JValue cannot be applied to (http.HttpPackage[List[dispatch.json.JsObject]]) val status1 = JsonParser.parse(status1)

I unsure and can't figure out what to do next in order to iterate through the data, extract it and render it to my web page.

+3  A: 

The error that you are getting back is letting your know that the type of status is neither a String or java.io.Reader. Instead, what you have is a List of already parsed JSON responses as Dispatch has already done all of the hard work in parsing the response into a JSON response. Dispatch has a very compact syntax which is nice when you are used to it but it can be very obtuse initially, especially when you are first approaching Scala. Often times, you'll find that you have to dive into the source code of the library when you are first learning to see what is going on. For instance, if you look into the dispatch-twitter source code, you can see that the timeline method actually performs a JSON extraction on the response:

def timeline = this ># (list ! obj)

What this method is defining is a Dispatch Handler which converts the Response object into a JsonResponse object, and then parses the response into a list of JSON Objects. That's quite a bit going on in one line. You can see the definition for the operand ># in the JsHttp.scala file in the http+json Dispatch module. Dispatch defines lots of Handlers that do a conversion behind the scenes into different types of data which you can then pass to block to work with. Check out the StdOut Walkthrough and the Common Tasks pages for some of the handlers but you'll need to dive into the various modules source code or Scaladoc to see what else is there.

All of this is a long way to get to what you want, which I believe is essentially this:

val statuses = http(Status(screenName).timeline)
statuses.map(Status.text).foreach(println _)

Only instead of doing a println, you can push it out to your web page in whatever way you want. Check out the Status object for some of the various pre-built extractors to pull information out of the status response.

Aaron
+3  A: 

Here's another way to use Dispatch HTTP with Lift-JSON. This example fetches JSON document from google, parses all "titles" from it and prints them.

import dispatch._
import net.liftweb.json.JsonParser
import net.liftweb.json.JsonAST._

object App extends Application {
  val http = new Http
  val req = :/("www.google.com") / "base" / "feeds" / "snippets" <<? Map("bq" -> "scala", "alt" -> "json")
  val json = http(req >- JsonParser.parse)

  val titles = for {
    JField("title", title) <- json
    JField("$t", JString(name)) <- title
  } yield name

  titles.foreach(println)
}
Joni