I'm very new to play! and scala and I'm trying to parse an array composed of json objects. I need to go through the array, count the number of specific occurrences in every object, add them up and pass them on to the html index. Here's what my controller would roughy look like:
object Application extends Controller {
def stringArray=<array of strings, each a JSValue>
var counter=0
for(i<-0 to stringArray.length){
counter+=(((Json.parse(stringArray(i))\"some_element").toString()).count(y=>y=="some_keyword"))
}
def index = Action {
Ok(views.html.index(counter))
}
}
But there's virtually no way to implement a for loop in the application controller. I've tried to pass on the array to index but other scala functions such as Json.parse and count seem to not be recognized the html template. What would be a possible workaround?
What about this?
object Application extends Controller {
val stringArray=<array of strings, each a JSValue>
def index = Action {
var counter = 0
for(s<-stringArray){
counter+=(((Json.parse(s)\"some_element").toString()).count(y=>y=="some_keyword"))
}
Ok(views.html.index(counter))
}
}
I haven't checked the inside part of the loop, but you seem to be confused about where to put the loop. Maybe this can be also rewritten as fold to have nicer code (for loops are generally considered not nice in Scala, as far as I understand ;) ). To use the functions in the templates, you may need to import them first. After the first line of template, where you declare the template function header, you can easily import stuff like for example: #import java.util.Date. Just make sure you import the correct class and you should be able to use the functions in templates as well.
And final note: 1 to 3 gives {1, 2, 3}, so you usually want 1 until array.length, as 1 until 3 gives {1, 2}. Usually you can use the for (element <- array) notation, which is easier to look at.
Related
I am using a groovy script within a Ready API test case to validate the results in a json web service response.
I want to use a variable (that is specified within a data source) to specify the json path that I want to validate, as this may change for each test run.
The following bit of code correctly assigns all the data referred to by the path results.address_components.long_name to the variable 'actualResponseOne'
def actualResponseOne = jsonSlurper.results.address_components.long_name.collect()
But, because within the same test I might want to validate different json elements ie. results.geometry.location_type for example I don't want to have the path hardcoded within the groovy script but instead set it up in a data source and assign it to a groovy variable within my script with ..
def testElementOne1 = context.expand( '${DataSource-Groovy-GoogleMaps#testElement1}' );
How to I refer to this json path within my code that assigns the data to 'actualResponseOne'? The below code doesn't work.
def actualResponseOne = jsonSlurper.${testElementOne}.collect()
Any help would be much appreciated.
regards,
Tam.
An alternative to using Eval would be to add a helper method to break apart the path and traverse it iteratively:
class Nested {
static class A {
B b
}
static class B {
C c
}
static class C {
List list
}
static void main(String[] args) {
def a = new A(b: new B(c: new C(list: [1, 2, 3])))
println getNestedProperty(a, "b.c.list").collect { String.format "%03d", it }
}
static def getNestedProperty(def object, String path) {
path.split(/\./).each {
object = object."${it}"
}
return object
}
}
[001, 002, 003]
The way I understand it is that GPath doesn't traverse dots [See this stack overflow question and this Groovy language bug]. You may have to break out the Eval class to force that to be evaluated. Perhaps something like?
ourPath = "results.address_components.long_name"
Eval.x( ourPath, "jsonSlurper.${x}.collect()" )
I am having a problem for which I cannot find a solution anywhere in the jBehave documentation. I have a story like this:
Given We have a JSON {boo: <boo>, foo: <foo>}.
When We get this.
Then We shall assert.
Examples:
|boo|foo|
|3|4|
And a step like this:
#Given("We have a JSON {$obj}.")
public void given(#Named("obj") final OwrObj obj) {
// Some code...
}
I also have a custom parameter converter which converts to OwrObj objects. My problem is that the converter gets a String input:
"{boo: <boo>, foo: <foo>}"
instead of:
"{boo: 3, foo: 4}".
In short, what is inside the curly brackets is seen as a parameter value.
Does anyone have any ideas on how to accomplish what I am trying to do. That is, get a custom object from a parametarised JSON structure in the story?
I'm trying to learn Scala and the Play Framework at the same time. Scala looks to me like it has a lot of really cool ideas, but one of my frustrations is trying to understand all of the different syntaxes for methods/functions/lambdas/anonymous functions/etc.
So I have my main application controller like so:
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
This tells me I have a singleton Application that has one method, index, that returns what type?? I was expecting index to have a definition more like:
def index(req: Request) : Result = { ... }
Looking at Play Framework's documentation, it looks as though Action is a trait, that transforms a request to a result, by I'm having a hard time understanding what this line is saying:
def index = Action { ... }
I come from a Java background, so I don't know what this is saying? (this statement feels like it's saying "method index = [some interface Action]", which doesn't make sense to me; it seems something beautiful is happening, but it is magic to me, and I feel uneasy with magic in my code ;))
When you invoke an object as if it were a function, that's translated into a call to apply. I.e.:
foo(bar)
is translated into
foo.apply(bar)
So, inside index you are calling the Action object as if it were a function, which means you are actually calling Action.apply.
The return type of index is omitted because the compiler can infer it to be the return type of Action.apply (which I guess from the name is Unit).
So the short answer to this question is that there's some stuff going on behind the scenes that makes the above work: namely that the compiler is inferring types, and in Scala, objects with an apply method can get called as if they were functions.
So what's going on here is that this code:
def index = Action {
Ok("Hello World!")
}
...is equivalent to (or rather shorthand for) this code:
def index : Action[AnyContent] = Action.apply(
(req: Request[AnyContent]) => {
Ok(views.html.index("Hello World!"))
} : Result
)
The magic is happening here: ... = Action {...}. Action {...} says "call Action with this anonymous function {...}".
Because Action.apply is defined as apply(block: => Result): Action[AnyContent], all of the argument-/return- types can be inferred.
What do i need to do to extract the value for friends_count. i noticed that screen_name are already define in the Status object and case class. Do still require to extends Js or JsObject different
object TweetDetails extends Js { val friends_count = 'friends_count ? num }
and then pattern match it against each json object in the list of JsObjects as represented below. The symbols are confusing:
scala> val friends_count = 'friends_count ! num // I wish SO understood Scala's symbols
val twtJsonList = http(Status("username").timeline)
twtJsonList foreach {
js =>
val Status.user.screen_name(screen_name) = js
val Status.text(text) = js
val friends_counts(friends_count) = js //i cannot figure out how to extract this
println(friends_count)
println(screen_name)
println(text)
}
Normally, Scala symbols can be thought of as a unique identifier which will always be the same. Every symbol that is lexi-graphically identical refers to the exact same memory space. There's nothing else that's special about them from Scala's point of view.
However, Dispatch-Json pimps out symbols making them JSON property extractors. To see the code which is responsible for the pimping, check out the SymOp class and the rest of the JsonExtractor.scala code.
Let's write some code which solves the problem you are looking at and then analyze what's going on:
trait ExtUserProps extends UserProps with Js {
val friends_count = 'friends_count ! num
}
object ExtUser extends ExtUserProps with Js
val good_stuff = for {
item <- http(Status("username").timeline)
msg = Status.text(item)
user = Status.user(item)
screen_name = ExtUser.screen_name(user)
friend_count = ExtUser.friends_count(user)
} yield (screen_name, msg, friend_count)
The first thing that we're doing is extending the UserProps trait in the Dispatch-Twitter module to give it a friends_count extractor and then defining a ExtUser object which we can use to get access to that extractor. Because the ExtUserProps extends UserProps, which also extends Js, we get the method sym_add_operators in scope which turns our symbol 'friends_count into a SymOp case class. We then call the ! method on that SymOp which we then pass the Extractor num to, which creates an Extractor that looks for a property "friends_count" on a JSON object and then parses it as a number before returning. Quite a bit going on there for such a small bit of code.
The next part of the program is just a for-comprehension that calls out to the Twitter timeline for a user and parses it into JsObjects which represent each status item, them we apply the Status.text extractor to pull out the status message. Then we do the same to pull out the user. We then pull the screen_name and friend_count out of the user JsObject and finally we yield a Tuple3 back with all of the properties we were looking for. We're then left with a List[Tuple3[String,String,BigDecimal]] which you could then iterate on to print out or do whatever with.
I hope that clears some things up. The Dispatch library is very expressive but can be a little tough to wrap your head around as it uses a lot of Scala tricks which someone just learning Scala won't get right away. But keep plugging around and playing with, as well as looking at the tests and source code, and you'll see how to create powerful DSL's using Scala.
I am trying grab all the member variables in AS3, and then foreach one i would like to process it in various ways. I would need the name and then if it is a collection of some type I would like to loop through that collection as well. I am attempting to essentially serialize in a somewhat custom fashion.
Thanks!
If you're looking to serialize an object, you will definitely want to use JSON.
JSON basically converts objects into strings and also the other way round using an encode()/serialize() and decode()/deserialize() function.
There is a built-in JSON class in AS3, and it's really easy to use.
Once you do something like:
var myObject:Object = {};
var myObjectString:String = JSON.serialize(myObject);
After getting the string, you can do all your switch logic to manipulate each of your different variables and convert it back into an object via the deserialize() function.
You could use describeType. That returns information about the object as XML. By default, you can iterate over public properties in objects. You could try something like...
// the object to iterate over
var someObj:Object = {};
for(var prop:String in someObj) {
// check to see if its something you want to iterate over
if (someObj[prop] is Array) {
// iterator over the property here
}
}
I hope this answers your question.