Not able to dot or bracket notation walk nested hyphenated JSON objects

Enea1
Tera Expert

Hello,

 

I am pulling JSON data from a third party API. The data object (although truncated to only show one), looks like this:

 

{
    "data": [
        {
            {
            "id": "625",
            "type": "projects",
            "attributes": {
                "object-type": "Project",
                "team-id": 2,
                "team": {
                    "id": 2,
                    "object-type": "Team",
                    "name": "Test team name",
                    "created-at": "2019-12-17T05:11:41.711Z",
                    "updated-at": "2022-12-12T20:54:11.504Z"
                },
                "purchasing-agency-id": 77,
                "purchasing-agency": {
                    "id": 77,
                    "team-id": 2,
                    "name": "Test Agency Name",
                    "twitter-link": "https://twitter.com/fsdfsdf",
                    "facebook-link": "https://www.facebook.com/sdfsdfsdfsdf",
                    "youtube-link": "https://www.youtube.com/cfdsfsfd",
                    "email": "mailto:webmaster@sdfdsfsfsfsdfs.com",
                    "created-at": "2020-07-24T00:31:20.363Z",
                    "updated-at": "2022-09-01T23:57:21.694Z"
                },
                "name": "Test software name",
                "status": "archived",
                "published-at": null,
                "archived-at": "2021-01-26T18:56:27.496Z",
                "procurement-official-id": 214,
                "procurement-official": {
                    "id": 214,
                    "object-type": "Membership",
                    "team-id": 2,
                    "user-id": 154,
                    "user": {
                        "id": 154,
                        "first-name": "Jim",
                        "last-name": "Hanson",
                        "email": "jim.hanson@yahoo.com",
                    }
        }
    ]
}

 

 
 
I am trying to set up a scheduled job script that will pull this data and update records on my instance every day.
 
To test the data, I am trying to access for example, the first name of the individual. 
After setting the following variables:

 

var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
var parser = new JSONParser();
var parsed = parser.parse(responseBody);

 

 
This works and I get a name showing in the logs:

 

​gs.log(parsed.data[1]['attributes']['procurement-official']['user']['first-name']


however, the moment I put it inside any sort of loop, it breaks down and no longer returns what I need. The log is just filled with system logs that are difficult to parse through but they don't even seem related.

 


I have tried with and without quotation marks along with every combination of dot/bracket walking possible:

 

for (var key in parsed.data) {
       gs.info("Key is: " + key + " and value is: " + parsed.data[key]['attributes']['procurement-official']['user']['first-name']);
}

 

...

 

​for (i = 0; i < parsed.data.length; i++) {
gs.log(parsed.data[i]['attributes']['procurement-official']['user']['first-name']);
}


For some reason, if I log everything up to

['user']

 I do get: 

 

 

2022-12-15 11:57:01
InformationKey is: 279 and value is: [object Object]*** ScriptLog Entry

 

So it's picking up that an object exists.. it just wont let me go into the last key of that object.

Again, outside of the loop and targeting one object, the notation seems to work.

 

Any ideas what I'm doing wrong with the loop?

 

Thank you in advance.

1 ACCEPTED SOLUTION

Enea1
Tera Expert

I think I solved the issue. You cannot iterate through null values at all. The loop breaks the moment it hits a null object. You HAVE to check for null and skip the iteration using "continue". You also have to check for the string value of "null" and not just the keyword null.

This is working and providing me with the first name of all the users it iterates on:

 

 

 

try {
    var r = new sn_ws.RESTMessageV2('STP CI Solicitation', 'Default GET');

    var response = r.execute();
    var responseBody = response.getBody();
    var httpStatus = response.getStatusCode();
    var parser = new JSONParser();
    var parsed = parser.parse(responseBody);

    gs.info(httpStatus);

    for (i = 0; i <= 10; i++) {
        var userVariable = JSON.stringify((parsed.data[i]['attributes']['procurement-official']['user']));
        if (userVariable != "null") {
            gs.info(JSON.stringify((parsed.data[i]['attributes']['procurement-official']['user']['first-name'])));
        } else {
            continue;
        }

    }

} catch (ex) {
    var message = ex.message;
    gs.error("This is the ex error message" + message);
}

 

 

 

 Thank you all for the help.

View solution in original post

17 REPLIES 17

Hi there,

 

The fact that you're running a try-catch and it is triggering the exception tells me there is some sort of issue with the JSON object being returned as the response body. Perhaps the size of the JSON string is too large as you have suggested which is causing it to be an invalid JSON object to try and parse.

 

Could you please log the ex.message to see more specifically what the exception/error is?

If this answer is helpful please mark correct and helpful!

Regards,
Chris Perry

Thank you Chris; here is the error message:

} catch (ex) {
    var message = ex.message;
    gs.error("This is the ex error message" + message);
}



*** Script: This is the ex error messageCannot read property "first-name" from null: no thrown error


objects error 3.png

jaheerhattiwale
Mega Sage
Mega Sage

@Enea1 There is one issue in object format.

The below marked object is present without key, thats wrong. Please check that.

jaheerhattiwale_0-1671558478658.png

Please mark as correct answer if this solves your issue.

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

Hello Jaheer,

 

It's not, I assure you. The payload has 33k lines in it and when I first posted this question, I took one object from the array. In my inattention, I added an extra bracket that should not be there. The follow up replies address this. Apologies for the confusion. The payload is structured correctly and starts in this way:

{
    "data": [
        {
            "id": "612",
            "type": "projects",
            "attributes": {
                "object-type": "Project",
                "team-id": 2,
                "team": {

...

 again, if I loop through and print only the user object, I get the object for all of them.. It is only a matter of the very last nested object inside user that is giving me problems.

@Enea1 Please try this

<OBJECT RECEIVED>.data[0].attributes["procurement-official"].user["first-name"]
Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023