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

@Mark Roethof - It is still not working

 

***EDIT***

Please see my response to @Prasad Pagar . I think my issue is in my nested loop, I am not comparing the right items in my record1 and record2 objects. 

How can I compare the values from record1 object to record2 object?

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.

Thanks for your response Janos!

That makes sense. I tried updating the code and using getValuesOf(gr), but getValuesOf() returns undefined when running my background script.

This is the script I ran:

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 = getValuesOf(gr);
		} else if(i == 1) {
			record2 = getValuesOf(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();

Can you replace 

record1 = getValuesOf(gr);

with 

record1 = gr.sys_id;

& so for record2 as well & print for a check.

Yeah, sorry, I should have been clearer, that function is not something that exists, should be implemented by you 🙂