How to populate an array of objects for a scripted rest api response
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-03-2021 02:28 PM
I'm building a scripted rest api for a custom integration, which should allow our partner to GET information based on a custom ID field on the company table, and return an array of values for the companies which match this value.
The script is correctly finding all of the company records which match the ID passed in the parameter, but when writing to the "company_records" array, the first company in the list is being returned twice, instead of the name of the two unique companies. When adding logging within the "while" statement, the two separate names are recognized. What am I doing wrong here?
Once this piece is working as expected, I'm going to need to go a layer deeper, and include an array nested within the company record to display all incidents currently open against each company. I originally had that query running also, but was getting the same issue where 3 incidents were returned for company 1, but the information for all 3 of them was only from the first incident in the list. I removed the Incident lookup
Script in the REST Resource:
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var pathParamsVar = request.pathParams;
var r4bid = pathParamsVar.id;
//define objects and arrays
var _master = {
"company_record_count": '',
"company_records": []
};
var _company = {
"id": '',
"name": '',
"company_incidents": []
};
//lookup company by ID
var comp = new GlideRecord('core_company');
comp.query('u_id', id);
comp.query();
_master.company_record_count = comp.getRowCount();
while (comp.next()) {
_company.id = comp.u_id;
_company.name = comp.name;
_master.company_records.push(_company);
}
response.setBody(_master);
})(request, response);
Response I'm getting, is successfully detecting there are 2 records with this ID applied, but Company 1 is being returned in the array twice, instead of both companies being returned:
{
"result": {
"company_record_count": 2,
"company_records": [
{
"id": "R4B0000135257",
"name": "Company 1",
"company_incidents": []
},
{
"id": "R4B0000135257",
"name": "Company 1",
"company_incidents": []
}
]
}
}
- Labels:
-
Integrations
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-03-2021 03:52 PM
I think your difficulty is probably here:
_company.id = comp.u_id;
_company.name = comp.name;
These lines of code are essentially saying "make _company.id a reference to comp.u_id" and the same for comp.name. They are not setting a static string value like you might think they are. This is a problem because for every iteration of comp.next(), the value stored in comp.u_id and comp.name changes to the value of those fields in the next record. As a result, all of the listings in _master.company_records will have the values of comp.u_id and comp.name for the last record the while loop iterates over.
To avoid this problem, you need to assign string values instead of references to GlideElements. There are several ways that you can do this. All of these different methods would work:
_company.id = comp.getValue("u_id");
_company.id = comp.u_id.getValue();
_company.id = comp.u_id.toString();
_company.id = comp.u_id + "";
I would recommend that you use one of the getValue() options, though. I have encountered cases where .toString() will return the result of getValue() if you log it out in a server script but it will pass the result of getDisplayValue() to the client side in a REST response.
So I'd recommend that you update it like this:
_company.id = comp.getValue("u_id");
_company.name = comp.getValue("name");
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-04-2021 01:37 PM
Thanks Tony,
Getting the display values got me part way there. I discovered that I was also missing a step when pushing the results to the array. I needed to parse, and stringify each object as it was pushed.
_master.company_records.push(_company);
becomes
_master.company_records.push(JSON.parse(JSON.stringify(_company)));
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-04-2021 03:15 PM
Glad to hear you got it working!
I don't think you should need to do that for every company record that you push into the company_records array. You can probably just stringifying the whole _master object once before sending it back.
response.setBody(JSON.stringify(_master));
Then you can use JSON.parse (or the equivalent function in the language your client is using) on the client side of your integration to turn it back into an object. That's been my experience, at least.