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

I checked that record in json data we have Test01 as value.. it should be the json.

Viraj Hudlikar
Tera Sage

Hello @Priyanka_77 

 

The issue arises because the costCentreResponsibleId object itself might be undefined when the id property is missing. The !gs.nil() check only verifies if the property exists, but it doesn't handle the case where the parent object is undefined.

 

 

(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 (jsonData.addChangeCostCentre.detailedCostCentre && 
                !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.description)) {
                cost.setValue('description', jsonData.addChangeCostCentre.detailedCostCentre.description);
            }

            if (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.');

})();

 

 

In this script, I've added checks to ensure that detailedCostCentre and costCentreResponsibleId exist before accessing their properties. This should prevent the "Cannot read property 'id' from undefined" error.

 

If my response has helped you hit helpful button and if your concern is solved do mark my response as correct.

 

Thanks & Regards
Viraj Hudlikar.

Juhi Poddar
Kilo Patron

Hello @Priyanka_77 

The issue occurs because gs.nil() only checks for null or empty values, but it does not check if an object or property exists.

Try this 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 (jsonData.addChangeCostCentre.detailedCostCentre.hasOwnProperty("description") && !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.description)) {
				gs.info('description: ' + jsonData.addChangeCostCentre.detailedCostCentre.description);
                cost.setValue('description',jsonData.addChangeCostCentre.detailedCostCentre.description);
            }

            if (jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.hasOwnProperty("id") && !gs.nil(jsonData.addChangeCostCentre.detailedCostCentre.costCentreResponsibleId.id)) {
				gs.info('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.');
})();

Note: hasOwnProperty("key") checks if the key is present in an object.

Hope this helps!

 

"If you found my answer helpful, please like and mark it as an "accepted solution". It helps future readers to locate the solution easily and supports the community!"

 

Thank You
Juhi Poddar