Procjess JSON of unknown Formats - javascript

a Services provides the following Information via JSON
{"errors":{"subject":"foobar"}}
and further alements in this errors array
OR
{"ok":{"subject":"foobarfoobar"}}
and further alements in this ok array array
So always either of the two is present, not both at once. Any as one is not present I always get an access error as one the proeprties is of course not existing
And I completely fail how to process this result. I always get "can not ... of undefined":
Currenlty I have:
if (data[0].hasOwnProperty("status")) {
alert('ddd');
}
What is the correct way to test, if either errors or ok is provided?
UPDATE
blex is right: But on the serverside is use:
echo json_encode( array('errors' => $result['errors']) );
Doesnt this mean I that errors is already the first element of an array? Why is this seen as an object propety?
SOLUTION/LEARNING:
Beware of PHP! As stated above echo json_encode( array('errors' => $result['errors']) ); does NOT lead to encoding this as an JSON Array. What I missunderstood and oversaw was, that { is the Format/Notation for Objects NOT for Arrays. So to be an array it would have to be [ . So in the End PHP does encode Associative Arrays as normal Object Properties not as arrays. That was my wrong assumption

var x = { "errors": { "subject": "foobar" } };
//var x = { "ok": { "subject": "foobarfoobar" } };
if (x.errors) {
} else if (x.ok) {
}

Essentially, you're already on the right track. hasOwnProperty is the right way to check for the existence of these keys.
I'm not sure what language you're using, but it seems like json_encode is converting your array to a single object, then putting that object under the errors key.
One last thing, you should probably look into using HTTP response codes. If you can return a 200 OK for the okay scenario, and a 400 or 500 level code for your error, then you'll be able to use better methods of determining how to process these situation. jQuery.ajax has the ability to put two handlers in place, one for success and one for failure, for instance.

Related

CognitiveServices POST response: data.hasOwnProperty failing for all but root of nested JSON object using raw JS

I am posting a request to Azure Cognitive Services (sentiment API) which returns a nested JSON object as follows (this is a JSON.stringify object output):
{ "error": "{\"documents\":[{\"id\":\"1\",\"sentiment\":\"neutral\",\"documentScores\":{\"positive\":0.15,\"neutral\":0.8,\"negative\":0.05},\"sentences\":[{\"sentiment\":\"neutral\",\"sentenceScores\":{\"positive\":0.15,\"neutral\":0.8,\"negative\":0.05},\"offset\":0,\"length\":4}]}],\"errors\":[],\"modelVersion\":\"2019-10-01\"}" }
I have spent 3 days trying and failing to access the nested key:values using javascript, so I can write individual keys/values to HTML elements using raw JS.
I've validated the JSON is correct using jsonlint.com
I've tried removing '/' characters by both re-parsing, and .replace, but the "cleaned" JSON still does not provide access to documents[]
I've used the following function, found on SO, to validate the stringify string against the object:
//Get nested object structure with key names
function traverse_it(data){
for(var prop in data){
if(typeof data[prop]=='object'){
// object
traverse_it(data[prop[i]]);
}else{
// something else
alert('The value of '+prop+' is '+data[prop]+'.');
}
}
}
traverse_it(data);
I've used data.hasOwnProperty to test for property existence - the only property that returns TRUE is "error":
//Check for individual properties
if(data.hasOwnProperty("error")){
console.log(data.error);
alert('yippidydippity')
}else{
alert('nope')
}
Attempts to access error.documents, error.documents[0].id, or locate the documents array all fail. I've searched through similar problems on SO but have not found anything that works.
How can I access the individual keys and values of this object using JS? Many thanks in advance!!!
try this
let obj = { "error": "{\"documents\":[{\"id\":\"1\",\"sentiment\":\"neutral\",\"documentScores\":{\"positive\":0.15,\"neutral\":0.8,\"negative\":0.05},\"sentences\":[{\"sentiment\":\"neutral\",\"sentenceScores\":{\"positive\":0.15,\"neutral\":0.8,\"negative\":0.05},\"offset\":0,\"length\":4}]}],\"errors\":[],\"modelVersion\":\"2019-10-01\"}" }
let obj2 = JSON.parse(obj.error)
//now you can access id from object
console.log(obj2.documents[0].id)

POSTMAN: Comparing object Environment variable with response's object

I am having a problem with comparing object typed Env variable with the response's object in Postman even though it seems the same and couldn't find answers anywhere.
Here's the example:
The object used is:
"user":
{
"id" = 1,
"first_name": "John",
"last_name": "Smith"
}
When using a POST request I save the object as Environment Variable using:
var reqdata = JSON.parse(data.request);
postman.setEnvironmentVariable("User", JSON.stringify(reqdata.user));
and then in a GET response I want to compare it by using:
Pre-request Script:
user = JSON.parse(postman.getEnvironmentVariable("User"));
and then in Tests:
var data = JSON.parse(responseBody);
tests["user contains correct data"] = data.user == user;
console.log(data.user);
console.log(user);
The console.log returns exactly the same objects but I am still getting fail. I tried using Object.is() and === but it still returns fail. Could somebody please tell me what I am missing?
Cheers
I have found a solution, I've used:
tests["user contains correct data" = JSON.stringify(data.user) == JSON.stringify(user);
And I can also just delete the test script and use bare postman.getEnvironmentVariable instead of the second stringify().
You can find better solutions to your problem in a very similar question here:
How to write a postman test to compare the response json against another json?
I had a similar problem to solve except that my JSON also contained an array of objects.
My answer in this question or one of the other answers will provide a more stable solution for comparison.
I created an array of global functions called "assert", which contained helper functions such as "areEqual" and "areArraysOfObjectsEqual" and saved these under the "Tests" tab at a top folder level of my tests.

Acessing JSON Information by order

I am reading information from a JSON string, and when I execute
console.log(record.seenTime.time.seenEpoch)
it display the right information.
But when I use console.log(record.seenTime.time[0].seenEpoch), I get an error saying :
TypeError: Cannot read property 'seenEpoch' of undefined.
Here is an example set of data:
{
seenTimes: {
time: {
seenTime: '2014-09-10T20:18:32Z',
seenEpoch: 1410380312
}
}
}
Anyone know what am I doing wrong?
Thanks
record.seenTimes in this case is an Object, not an Array, you can verify that using
typeof record.seenTimes
Because of that, time[0] returns undefined.
seenEpoch is a property of the ONE AND ONLY time object, therefore, you access it using record.seenTimes.time.seenEpoch
For once, I'll recommend reading something from w3schools : JSON Syntax
It'll show you examples of what can be stored in JSON.
EDIT :
Your sample record.seenTimes will not be able to store multiple time objects, as it uses the curly brackets {} which indicate that it's meant to store an object , if you want to be able to store multiple time objects, ie: an Array, your JSON will have to look like :
record {
seenTimes: [
{
time: {
seenTime: '2014-09-10T20:18:32Z',
seenEpoch: 1410380312
}
},
{
time: {
seenTime: '2014-09-10T20:18:32Z',
seenEpoch: 1410380312
}
}
]
}
Note the square brackets that say that seenTime holds an array.
And as slebetman noted :
Also note that in javascript, an object defined as having multiple
identical keys are technically invalid. But most implementations take
the last definition. For example, the object: {a:1,a:2,a:3} is exactly
the same as {a:3}. So if you don't use an array then there is only one
time object even if it appears twice in the JSON string.

How to get data from JSON response?

I am using plain JavaScript on my project. How can I get the value of the following example with the category? I need to detect whether it comes back true or false.
{
"category": "true"
}
I can get the entire object, but I just want to pull out the value of category.
from comment...
The JSON data is returned from the server based on a form submission. It keeps saying myObject is undefined. How can do I pass this so my JavaScript can read the response?
from comment...
I can get myObject using this: if (form.XHR.status === 200) {var data = form.XHR.response;}, but if I try to do data.myObject it says it's undefined.
You need to parse the JSON before you can access it as an object...
if (form.XHR.status === 200) {
var data = form.XHR.response;
var parsed = JSON.parse(data);
alert(parsed.category);
}
Why is this needed? It's because JSON is not JavaScript. The two terms are not synonymous.
JSON is a textual data interchange format. It needs to be parsed into the data structures of whatever language it's been given to. In your case, the language is JavaScript, so you need to parse it into JavaScript data.
When it is received form the xhr response, it is received in the form in which all textual data is handled in JavaScript. That is as a string. As a string, you can't directly access the values represented.
JavaScript has a built in parser called JSON.parse. This was used in the example above to do the necessary conversion.
Some older browsers don't support JSON.parse. If you're supporting those browsers, you can find a JavaScript parser at http://json.org .
First of all you need a variable to refer it:
var obj = {
"category": "true"
};
Then can you say e.g:
alert(obj.category);
var myObject = { "category": "true"};
alert (myObject.category);
But you likely want:
var myObject = { "category": true};
...if you're going to be testing for true/false:
if (myObject.category) {
// category is true, so do your stuff here.
}
You can access json object data using '.' or [key] like this :
var obj = {
"category": "true"
};
console.log(obj.category);
// Or
console.log(obj["category"]);
Here is the DEMO
For anyone who arrives here banging their head against the wall, make sure to see if you need to access a parent object which wraps all the delivered data:
console.log(response['id'])
may not work, because a parent entity must be accessed first:
console.log(response.session['id'])
If you console log your response and it is wrapped in {} you probably need to do this.

getting access to jQuery.parseJSON(result) or transforming it into javascript array or smth

result = jQuery.parseJSON(result);
for(var k in result)
{
alert(k);
alert(result[k]);
}
This code is working just fine.
But let's suppose I'm receiving object of the following type
status='FALSE'
message='error'
If you want to echo all this things first code is ok. It will alert everything.
But what If I want to work with this data, do some manipulations. In this case this for loop is a bit bad idea for me. So I have to transform probably this data into something new. Maybe constract some array during this loop and then read from array ? I think there must be some simple way to get access to that data. Please help
If result is JSON data, you should be able to simply do:
result = jQuery.parseJSON(result);
alert(result.status);
alert(result.message);
pareJSON turns the JSON data into a JavaScript Object. To access properties of an Object in JavaScript, you need to use dot notation.

Categories