Iterating over a JSON array in scala - json

I'm using the JSON lib net.sf.json(http://json-lib.sourceforge.net/apidocs/net/sf/json/package-summary.html) in my scala code.
Also, I'm using the specs BDD framework (http://code.google.com/p/specs/) for unit testing. In the doBefore block, i have the following code:
doBefore {
iter = serversJSON.iterator()
}
serversJSON is a JSONArray object. Outside the doBefore block, I have declared the variables used as follows
var serversJSON:JSONArray = null
var iter:Iterator[JSONArray] = null
But on compilation I'm getting the following error.
error: type mismatch; found :
java.util.Iterator[?0] where type ?0
required:
java.util.Iterator[net.sf.json.JSONArray]
iter = serversJSON.iterator()
I guess the way i have declared the iter object outside doBefore is incorrect. How to fix this?
Please Help
Thank You.

As indicated here, the JSON library's iterator method returns a raw Iterator, not an Iterator[JSONArray]. You'll want to declare it as follows:
var serversJSON:JSONArray = null
var iter:Iterator[_] = null

Related

How do parse a json object in Action Script 3?

I am trying to use the Kairos API for Facial Recognition in my air app. After i send the image, kairos returns the following JSON:
{"images":[{"transaction":{"status":"failure","topLeftX":106,"topLeftY":126,"gallery_name":"Faces","eyeDistance":42,"height":98,"width":98,"face_id":1,"quality":-1.53973,"message":"No match found"}}],"uploaded_image_url":"https:\/\/kairos-east-id-images.s3.amazonaws.com\/prod\/c6d565457\/recognize\/Faces\/d2b1142f2134232349ewer8acb825c87e909f299ab1_5a234XXXXXX.jpg?X-Amz-Content-Sha246=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXXXXXXXXXXX-east-1%2Fs3%2XXXX_request&X-Amz-Date=2017122rrtdfg158Z&X-Amz-SignedHeaders=host&X-Amz-Expires=XXXX&X-Amz-Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
I need to access the values of "topLeftX", "topLeftY" and "message" but no matter what i try it doesn't seem to work. I have been searching around for about an hour. I have tried both native JSON parser and ascorelib JSON parser.
I tried the following:
var rawData:Object = JSON.decode(e.target.data);
for ( var object:Object in rawData ){
trace(object.transaction);
}
I get this error:
Property transaction not found on String and there is no default value.
I tried with different property names but I get the same error. I have tried sever other methods as well. Such as,
rawData["transaction"][0]["topLeftX"]
It doesnt work.
Any help is greatly appreciated.
I do not have a decode function on JSON. Just a JSON.parse and a JSON.stringify however what should work for you is this.
var jsonObj = JSON.parse(yourdata); // or JSON.decode if you AS version is older
for ( var i = 0 ; i < jsonObj.images.length ; i++ ){
trace(jsonObj.images[i].transaction.status);
}

how to Validate if JSON Path Exists in JSON

In a given json document, how to validate if a json path exists ?
I am using jayway-jsonpath and have the below code
JsonPath.read(jsonDocument, jsonPath)
The above code can potentially throw below exception
com.jayway.jsonpath.PathNotFoundException: No results for path:
$['a.b.c']
In order to mitigate it, I intend to validate if the path exists before trying to read it with JsonPath.read
For reference I went through the following 2 documentations, but couldn't really get what I want.
http://www.baeldung.com/guide-to-jayway-jsonpath
https://github.com/json-path/JsonPath
Whilst it is true that you can catch an exception, like it is mentioned in the comments there might be a more elegant way to check if a path exists without writing try catch blocks all over the code.
You can use the following configuration option with jayway-jsonpath:
com.jayway.jsonpath.Option.SUPPRESS_EXCEPTIONS
With this option active no exception is thrown. If you use the read method, it simply returns null whenever a path is not found.
Here is an example with JUnit 5 and AssertJ showing how you can use this configuration option, avoiding try / catch blocks just for checking if a json path exists:
#ParameterizedTest
#ArgumentsSource(CustomerProvider.class)
void replaceStructuredPhone(JsonPathReplacementArgument jsonPathReplacementArgument) {
DocumentContext dc = jsonPathReplacementHelper.replaceStructuredPhone(
JsonPath.parse(jsonPathReplacementArgument.getCustomerJson(),
Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS)),
"$.cps[5].contactPhoneNumber", jsonPathReplacementArgument.getUnStructuredPhoneNumberType());
UnStructuredPhoneNumberType unstructRes = dc.read("$.cps[5].contactPhoneNumber.unStructuredPhoneNumber");
assertThat(unstructRes).isNotNull();
// this path does not exist, since it should have been deleted.
Object structRes = dc.read("$.cps[5].contactPhoneNumber.structuredPhoneNumber");
assertThat(structRes).isNull();
}
You can also create a JsonPath object or ReadContext with a Configuration if you have a use case to check multiple paths.
// Suppress errors thrown by JsonPath and instead return null if a path does not exist in a JSON blob.
Configuration suppressExceptionConfiguration = Configuration
.defaultConfiguration()
.addOptions(Option.SUPPRESS_EXCEPTIONS);
ReadContext jsonData = JsonPath.using(suppressExceptionConfiguration).parse(jsonString);
for (int i = 0; i < listOfPaths.size(); i++) {
String pathData = jsonData.read(listOfPaths.get(i));
if (pathData != null) {
// do something
}

parsing and applying conditional element on key value pair in typescript

I am doing an Ionic App with typescript.
I have some error condition as response from REST API,
I did
err._body
and it gives me
{"reason":"invalid_token"}
but when I do
err._body.reason
or
err._body.get("reason")
it gives undefined value.
I did JSON stringify and parse as well, no luck,
How to parse this and get the value so that I can apply specific processing for this.
First try to do
console.log(typeof err._body);
so we can be sure what the type of that is. If it's a string, you should do
let errorObj = JSON.parse(err._body);
// And then...
let errorMsg = errorObj.reason // or errorObj["reason"] as well
If it's an Object, you can skip the parse() part and just use it like this:
let errorMsg = err._body.reason // or err._body["reason"]

value in array concatenation with string not working

In the following code, I want to concatenate the data in array arr1 with string value in variable t.
var t:String;
var arr4:Array = new Array();
for(w;w<i;w++){
if(max==arr3[w]){
t=t.concat(",",arr1[w])
}
}
trace(t);
But I get this error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at final1_fla::MainTimeline/modebtn()
Can anyone help me?
That code doesn't make sense at all, arr4 is initialized but never used, instead arr3 and arr1 is used which might not be initialized and causing the null object reference error.
Your loop is using w which is not initialized and is comparing against i which isn't shown here.
Make sure your arrays are valid and check if that for loop is functioning as you expect it to.

NancyFX: How do I deserialize dynamic types via BrowserResponse.Body.DeserializeJson (unit tests)

I have the following NancyFX unit test. I use the Shouldly assertion library to give the set of extensions methods that start .Should---
[Fact]
public void Assessment__Should_return_assessment_state_for_specified_user()
{
const AssessmentState assessmentState = AssessmentState.Passed;
var user = Fake.Mentor();
using (var db = Fake.Db())
{
db.Save(user);
Fake.Assessment(user.Id, db, assessmentState);
db.ClearStaleIndexes();
}
var response = Fake.Browser(user.UserName, user.Password)
.Get("/assessment/state/" + user.Id, with => with.HttpRequest());
//var result = (dynamic)body.DeserializeJson<ExpandoObject>();
var result = (dynamic) JsonConvert.DeserializeObject<ExpandoObject>(response.Body.AsString());
result.ShouldNotBe(null);
((AssessmentState) result.State).ShouldBe(assessmentState);
}
This test calls a AssessmentService uri defined as /assessment/state/" + user.Id which returns a simple JSON object definition that has a single property State of type (enum) AssessmentState, either Passed, Failed or NotStarted.
Here is the service handler so you can see there are no tricks.
Get["/assessment/state/{userid}"] = parameters =>
{
var assessment = AssessmentService.GetByUserId(Db, (string)parameters.userid);
return assessment == null ? HttpStatusCode.NotFound : Response.AsJson(new
{
assessment.State
});
};
And here is an example the JSON this service call returns:
{"State":1}
Everything works fine until I try to Deserialize the JSON returned by the fake Nancy browser. First I tried to use the built in method provided by Nancy's BrowserResponse.Body object:
var result = (dynamic)response.Body.DeserializeJson<ExpandoObject>();
This deserializes to an empty object. Which is no good. However, if we use the Newtonsoft equivalent then everything is fine (almost).
var result = (dynamic) JsonConvert.DeserializeObject<ExpandoObject>(response.Body.AsString());
The JSON deserialization now works and so the following Shouldly assertion passes with flying colours:
((AssessmentState) result.State).ShouldBe(assessmentState);
However, for reasons that I suspect have to do with anonymous types, the following line fails at run-time (it compiles fine).
result.ShouldNotBe(null);
That is quite a lot of information. Let me distil it down to two questions:
Why does Nancy's built in JSON deserializer not work given that the Newtonsoft version does?
How do I work with the dynamic types generated by the JSON de-serialisation so that the Shouldly extension methods do not cause a run-time exception?
Thanks
I can't answer the first question, but WRT Shouldly and dynamic types, Shouldly's ShouldNotBe method is an extension method on object. The DLR doesn't allow you to call extension methods on objects typed as dynamic (hence the runtime binder exception you're seeing)
I'd suggest that if you want to call ShouldNotBe(null) on result, you'd have to cast it to an object first (ie: ((object)result).ShouldNotBe(null))
-x