- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-06-2025 02:41 PM
My script looks good, but the results I'm receiving are not what I'm expecting. Here's the script:
var startTime = 0;
var endTime = 0;
var grMetric = new GlideRecord('incident_metric');
grMetric.addEncodedQuery('inc_number=INC0007001^mi_definition=35f2b283c0a808ae000b7132cd0a4f55');
grMetric.query();
while (grMetric.next()){
if(grMetric.mi_value == ("Resolved")){
startTime = grMetric.mi_start;
gs.print("Start Time: " + startTime);
}else if(grMetric.mi_value == "Closed"){
endTime = grMetric.mi_start;
gs.print("End Time: " + endTime);
}
}
gs.print(" ");
gs.print("Start Time: " + startTime);
gs.print("End Time: " + endTime);
The attached file shows the results. How is the variable 'startTime' being overwritten? Any suggestions.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-06-2025 03:06 PM - edited ‎03-06-2025 03:08 PM
Your endTime (and startTime) are references, so they change on the next iteration of your loop when ServiceNow repopulates the property grMetric.mi_start to the value from next record. Can you try adding toString() to the end of your property access when storing the values? eg:
endTime = grMetric.mi_start.toString();
Also, for debugging, it may help to differentiate the log text in your loop vs the logs outside of your loop so it's clear what's printing what (gs.print doesn't always log in the order it's used).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-07-2025 09:53 PM
It's to do with how ServiceNow reuses the object references each time .next() is called. Internally, when you call .next() it updates the GlideElement's value (but reuses the same GlideElement object reference), and since endTime stores just a reference to the GlideElement, it changes too.
Example below on how it works (see code comments for mode details):
// .next() gets called the first time, this populates your GlideRecord object with the values from the database for the first row
var grMetric = { // <-- GlideRecord instance
mi_start: { // <-- GlideElement instance
_value: "XYZ", // value for first row
toString: function() {return this._value;} // implicitly called when you use `gs.print`/`gs.log` on the `mi_start` object.
}
// ... other fields ...
};
var endTime = grMetric.mi_start; // `endTime` is a reference that points to the mi_start GlideElement object in memory
// Next iteration occurs, `.next()` is called:
// - Here, when `.next()` is called, the existing GlideRecord/GlideElement objects in memory are updated, new ones are NOT created, so the existing objects' values are changed
grMetric.mi_start._value = "ABC"; // <-- Internally, ServiceNow updates the GlideElements value (something like this), but the object reference remains the same
gs.info(endTime); // this would now print "ABC", not "XYZ" since `endTime` just stores a reference to the GlideElement in memory, which `.next()` modifies.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-06-2025 02:47 PM
I made a slight mistake. The variable 'endTime' is the variable that is being overwritten. How?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-06-2025 03:06 PM - edited ‎03-06-2025 03:08 PM
Your endTime (and startTime) are references, so they change on the next iteration of your loop when ServiceNow repopulates the property grMetric.mi_start to the value from next record. Can you try adding toString() to the end of your property access when storing the values? eg:
endTime = grMetric.mi_start.toString();
Also, for debugging, it may help to differentiate the log text in your loop vs the logs outside of your loop so it's clear what's printing what (gs.print doesn't always log in the order it's used).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-07-2025 07:40 AM
Thanks Nick. That worked!!
Can you help me to understand how the variable was being overwritten before the script change.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-07-2025 09:53 PM
It's to do with how ServiceNow reuses the object references each time .next() is called. Internally, when you call .next() it updates the GlideElement's value (but reuses the same GlideElement object reference), and since endTime stores just a reference to the GlideElement, it changes too.
Example below on how it works (see code comments for mode details):
// .next() gets called the first time, this populates your GlideRecord object with the values from the database for the first row
var grMetric = { // <-- GlideRecord instance
mi_start: { // <-- GlideElement instance
_value: "XYZ", // value for first row
toString: function() {return this._value;} // implicitly called when you use `gs.print`/`gs.log` on the `mi_start` object.
}
// ... other fields ...
};
var endTime = grMetric.mi_start; // `endTime` is a reference that points to the mi_start GlideElement object in memory
// Next iteration occurs, `.next()` is called:
// - Here, when `.next()` is called, the existing GlideRecord/GlideElement objects in memory are updated, new ones are NOT created, so the existing objects' values are changed
grMetric.mi_start._value = "ABC"; // <-- Internally, ServiceNow updates the GlideElements value (something like this), but the object reference remains the same
gs.info(endTime); // this would now print "ABC", not "XYZ" since `endTime` just stores a reference to the GlideElement in memory, which `.next()` modifies.