Code not updating records

mballinger
Mega Guru

Hello,

I have a background script that does not seem to be working. It is supposed to copy all field values from 1 field to the next (duplicate field values should be copied to the most recently updated). I can print/log the values that are missing, but they are not updating.

I am also getting an error:

"Possible bad date set: com.glide.script.glide_elements.GlideElementReference"

"javascript eval for GlideDateTime returned" 

 

Here is my code:

var record1 = null;
var record2 = null;
var arr = [];
var gr = new GlideRecord('u_compliance');
gr.addEncodedQuery('active=true^u_type=fha');
gr.orderByDesc('sys_updated_on');
gr.setLimit(2);
gr.query();

for(var i =0; i < gr.getRowCount(); i++) {
	if(gr.next()) {
		if(i == 0) {
			record1 = gr;
		} else if(i == 1) {
			record2 = gr;
		}
	}
}

if(record1 != null || record2 != null) {
	for(var firstRecord in record1) {
		arr = [];
		if(record1[firstRecord] == '' || record1[firstRecord] == null) {
			for(var secondRecord in record2) {
				if(record2[secondRecord] != '' || record2[secondRecord] != null){
                                        arr.push("name: " + firstRecord + ": " + record2[secondRecord]);
					record1.setValue(firstRecord, record2[secondRecord]);
				}
			}		
		}
	}
        
        if(arr.length > 0) {
           gs.print("Updated fields: " + arr.toString());
        }
}

record1.setWorkflow(false);
record1.autoSysFields(false);
record1.update();
1 ACCEPTED SOLUTION

The problem is that you treat the GlideRecord object as if it was a non-mutating, constant object. An object that is different from one call of next() to the other, an object that represents the data in the database. But it is not. GlideRecord is an object that enables fetching the data for a field from a record when requested explicitly or implicitly. Calling the next() method on one hand does not result in a new object (that contains the data for the next record) on the other hand it does not fetch the data. The data is fetched only when one explicitly calls its getValue() method (e.g. gr.getValue('state');). Or when one calls the toString() method of one of its GlideElement properties (e.g. gr.state.toString();

Thus when you write

for(var i =0; i < gr.getRowCount(); i++) {
	if(gr.next()) {
		if(i == 0) {
			record1 = gr;
		} else if(i == 1) {
			record2 = gr;
		}
	}
}

it is actually the exact same thing as if you wrote:

for(var i =0; i < gr.getRowCount(); i++) {
	if(gr.next()) {
		record1 = gr;
		record2 = gr;
	}
}

You need to change the code so that instead of setting record1 and record2 to be equal to, in fact references to gr, it will at that moment fetch the values from the GlideRecord and adds those as properties of record1 and record2.

Something like:

for (var i = 0; i < gr.getRowCount(); i++)
	if (gr.next())
		if (i == 0)
			record1 = getValuesOf(gr);
		else
			if(i == 1)
				record2 = getValuesOf(gr);

Where function getValuesOf creates an in-line object, adds values of fields to that object as properties and finally returns that object.

An observation: you should not be calling gr.getRowCount(), especially on large data sets, it incurs a slight performance penalty as it sort of forces the system to traverse the record set twice: once to get the count the 2nd time to traverse it when calling next(). It's better to use a while loop and counter variable if needed, like is here.

View solution in original post

11 REPLIES 11

Prasad Pagar
Mega Sage

Hi,

By looking at first instinct try this

var record1 = null;
var record2 = null;
var arr = [];
var gr = new GlideRecord('u_compliance');
gr.addEncodedQuery('active=true^u_type=fha');
gr.orderByDesc('sys_updated_on');
gr.setLimit(2);
gr.query();

for(var i =0; i < gr.getRowCount(); i++) {
	if(gr.next()) {
		if(i == 0) {
			record1 = gr;
		} else if(i == 1) {
			record2 = gr;
		}
	}
}

if(record1 != null && record2 != null) {
	for(var firstRecord in record1) {
		arr = [];
		if(record1[firstRecord] == '' || record1[firstRecord] == null) {
			for(var secondRecord in record2) {
				if(record2[secondRecord] != '' && record2[secondRecord] != null){
                                        arr.push("name: " + firstRecord + ": " + record2[secondRecord]);
					record1.setValue(firstRecord, record2[secondRecord]);
				}
			}		
		}
	}
        
        if(arr.length > 0) {
           gs.print("Updated fields: " + arr.toString());
        }
}

gr.setWorkflow(false);
gr.autoSysFields(false);
gr.update();

@Prasad Pagar - Thanks for your response!

I updated the script with yours. It updated the secondary record and not the first. It also only took the first value and used that same value across all fields

Ex: type = compliant, type class = compliant, description = compliant, short description = compliant etc.

Mark Roethof
Tera Patron
Tera Patron

Hi there,

You are not actually updating anything on gr? You only have this:

gr.setWorkflow(false);
gr.autoSysFields(false);
gr.update();

Where's the fields/values to be updated?

If my answer helped you in any way, please then mark it as helpful.

Kind regards,
Mark
2020-2022 ServiceNow Community MVP
2020-2022 ServiceNow Developer MVP

---

LinkedIn
Community article, blog, video list

 

Kind regards,

 

Mark Roethof

Independent ServiceNow Consultant

10x ServiceNow MVP

---

 

~444 Articles, Blogs, Videos, Podcasts, Share projects - Experiences from the field

LinkedIn

@Mark Roethof - Thanks for your response. Sorry I manually wrote the script in the thread. I just updated the original post.