Cannot read property "id" from undefined

Priyanka_77
Tera Contributor

I have a table and on that i have a field JSON data which contains the JSON which is received from partner system as an inbound.
Now i am writing a fix script, which will read the fields from it like description and id and it will map into the table fields description and responsible id.

Below is the example with json data and the fix script:
JSON data: 
{
"addChangeCostCentre": {
"requestId": {
"requestId": "DUMMY1234567890123_0001"
},
"detailedCostCentre": {
"costCentreResponsibleId": {
"id": "99999999"
},
...etc
Below is the fix script:

(function executeFixScript() {

    gs.info('@PD fix script started');
    var cost = new GlideRecord('x_tsigh_basedata_icu_cost_center');
    cost.addNotNullQuery('json_data');
    cost.query();
    gs.info('@PD get row count: '+cost.getRowCount());

    while (cost.next()) {
        try {
            var jsonData = JSON.parse(cost.json_data);

           
            if (!gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.description)) {
                //cost.description = jsonData.addChangeCostCentre.detailedCostCentre.description;
                cost.setValue('description',jsonData.addChangeCostCentre.detailedCostCentre.description);
            }

           
            if (!gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id)) {
                //cost.responsible_id = jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id;
                cost.setValue('responsible_id', jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id);
            }
            gs.info('@PD Updating sys_id: ' + cost.sys_id +
                        ' | Description: ' + cost.description +
                        ' | Responsible ID: ' + cost.responsible_id);

            cost.update();
        } catch (e) {
            gs.error('Error parsing JSON for record: ' + cost.sys_id + ' - ' + e.message);
        }
    }

    gs.info('Fix script execution completed.');


})();
 
 
Scenario is json_data field may contain detailedCostCentre.description and responsible id..
When i have both in the json data, it is mapping correctly but when i have either one of them it is not. 
when i dont have responsible id(id) in the json data it is going into catch block and throwing error "Cannot read property id from undefined".
I have already used !gs.nil() to handle this but it is not working.

 

1 ACCEPTED SOLUTION

Ankur Bawiskar
Tera Patron
Tera Patron

@Priyanka_77 

try this and check if the object/property exists

Also the below code checks if the nested objects (addChangeCostCentredetailedCostCentre, and costCentreResponsibleId) exist before attempting to access their properties

(function executeFixScript() {
    gs.info('@PD fix script started');
    var cost = new GlideRecord('x_tsigh_basedata_icu_cost_center');
    cost.addNotNullQuery('json_data');
    cost.query();
    gs.info('@PD get row count: ' + cost.getRowCount());

    while (cost.next()) {
        try {
            var jsonData = JSON.parse(cost.json_data);

            // Check if 'description' exists in the JSON data
            if (jsonData.addChangeCostCentre && 
                jsonData.addChangeCostCentre.detailedCostCentre && 
                !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.description)) {
                cost.setValue('description', jsonData.addChangeCostCentre.detailedCostCentre.description);
            }

            // Check if 'costCentreResponsibleId.id' exists in the JSON data
            if (jsonData.addChangeCostCentre && 
                jsonData.addChangeCostCentre.detailedCostCentre && 
                jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId && 
                !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id)) {
                cost.setValue('responsible_id', jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id);
            }

            gs.info('@PD Updating sys_id: ' + cost.sys_id +
                    ' | Description: ' + cost.description +
                    ' | Responsible ID: ' + cost.responsible_id);

            cost.update();
        } catch (e) {
            gs.error('Error parsing JSON for record: ' + cost.sys_id + ' - ' + e.message);
        }
    }

    gs.info('Fix script execution completed.');
})();

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

View solution in original post

7 REPLIES 7

J Siva
Tera Sage

Hi @Priyanka_77 

As you said, the response payload might have id/description key.

gs.nil works only when there's a key with empty values. i.e., { "id":""}. But in your scenario the id key itself is not present, that's why it's throwing "Cannot read property id from undefined".

In order to validate if the "id" parameter is present or not you can use below script,

 

var hsdId ='id' in jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId;
If(hasId){
Setvalue...
}
Else{
Ignore..
}

 

Hope this helps 

Ankur Bawiskar
Tera Patron
Tera Patron

@Priyanka_77 

try this and check if the object/property exists

Also the below code checks if the nested objects (addChangeCostCentredetailedCostCentre, and costCentreResponsibleId) exist before attempting to access their properties

(function executeFixScript() {
    gs.info('@PD fix script started');
    var cost = new GlideRecord('x_tsigh_basedata_icu_cost_center');
    cost.addNotNullQuery('json_data');
    cost.query();
    gs.info('@PD get row count: ' + cost.getRowCount());

    while (cost.next()) {
        try {
            var jsonData = JSON.parse(cost.json_data);

            // Check if 'description' exists in the JSON data
            if (jsonData.addChangeCostCentre && 
                jsonData.addChangeCostCentre.detailedCostCentre && 
                !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.description)) {
                cost.setValue('description', jsonData.addChangeCostCentre.detailedCostCentre.description);
            }

            // Check if 'costCentreResponsibleId.id' exists in the JSON data
            if (jsonData.addChangeCostCentre && 
                jsonData.addChangeCostCentre.detailedCostCentre && 
                jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId && 
                !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id)) {
                cost.setValue('responsible_id', jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id);
            }

            gs.info('@PD Updating sys_id: ' + cost.sys_id +
                    ' | Description: ' + cost.description +
                    ' | Responsible ID: ' + cost.responsible_id);

            cost.update();
        } catch (e) {
            gs.error('Error parsing JSON for record: ' + cost.sys_id + ' - ' + e.message);
        }
    }

    gs.info('Fix script execution completed.');
})();

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Hi @Ankur Bawiskar ,
Your solution is working but getting just one error:
Error parsing JSON for record: c4dea919f7a0f950ec1ceeb899 - Unexpected token: T

@Priyanka_77 

Glad to know.

if my script is working then it should not throw any error.

which line is giving that error?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader