{!#LOOP} and before suffix lack functionality

Posted by matman on 08-Sep-2014 06:52

I was trying to implement a trigger that needs to delete detached related records on 'after update'. Before I can delete those records, I need to get all those detached records. One idea was to use {!#LOOP.R108244227#before}, which doesn't work because {!#LOOP} returns an Error. Another idea was to just use {!R108244227#before}, but for some reason this returns the same as rbv_api.getFieldValue().

Is there any way to get the values of a related field #before an update? I have tried several scripts, for example:

var x = "";
{!#LOOP_BEGIN.R108244227}
	x += {!id#before} + ", ";
{!#LOOP_END.R108244227}
rbv_api.log("debug", x);

All Replies

Posted by Orchid Corpin on 08-Sep-2014 10:00

Hi matman,

To delete detached records you compare the before values and current values of a child lookup, see sample code below just change the R56036 and 'product1':

var before = new Array({!R56036#before});
var after = new Array({!R56036});
var detachItem;
for(i=0; i < before.length; i++) {
  detachItem = after.indexOf(before[i]);
  if(detachItem == -1) rbv_api.deleteRecord("product1", before[i]);
}


Also you cannot see the #before values inside edit trigger debug since all records are already updated. You can use debug beside the New Trigger and Run Trigger then just add rbv_api.println(before); in the code above. Once you click the debug button a new window will open and try an actual editing of record then refresh the debug window to see the results.

Hope this may help.

Regards,

Orchid

Posted by matman on 09-Sep-2014 09:28

Unfortunately the new Array({!R....#before}) bugs. This is because JavaScript arrays cannot contain only one value. Since I have only one related record, the value of that record ID will become the value of var before. When calling .length on this var, it will return the value, which is something like 13904890, resulting in an infinite loop. Since my after var contains more than one elements, it does work correctly.

I will work around the problem using an examination to determine whether the length is larger than 10000.

How did you know you could use new Array() with the {!R.....}? I don't see this anywhere in the docs, nor a reason I should expect that would work.

Posted by Orchid Corpin on 09-Sep-2014 11:12

Hi matman,

Sorry I just thought you always have that multiple child values in your setup so I used new Array() to store your #before values which works perfectly for more than 1.
Seems that is a good idea to put the validation on it.

You can use new Array() as the trigger formula accepts pure javascript codes, this was not in the documentation since this is not Rollbase API, what was just stated in the documentation that object script trigger can run JavaScript.

See additional info in Chapter 5: Adding Business Logic > Workflow and Trigger > Trigger Types > Object Script
http://documentation.progress.com/output/Rollbase/RB_User_Guide.pdf

Hope this may help.

Regards,
Orchid

Posted by matman on 10-Sep-2014 04:15

Hey Orchid Corpin, thank you for your reply. I know we can use Javascript, but I don't understand why we can just put {!R108244227} into new Array(). When doing return "" + {!R108244227} it only returns the first ID, rather than all IDs. This makes me think that passing {!R108244227} will always create an array with only one element (which is that single ID), regardless of the amount of related records.

When passing only one argument to new Array(), it will create an array with that <b>length</b>, that's why .length worked for me. For example: new Array(10234234) will create an array with 10234234 indices :P I replaced the new Array() with [ ]. [ ] supports the creation of an array with only 0 or 1 elements, resulting in a .length of 0 or 1

Applying [ ] resulted in the following code:

var employeeIDsBefore = [{!R108244227#before}];
var employeeIDsAfter = [{!R108244227}];

if(employeeIDsBefore.length && employeeIDsAfter.length) {
	for(var i = 0; i < employeeIDsBefore.length; i += 1) {
		if(employeeIDsAfter.indexOf(employeeIDsBefore[i]) < 0) {
			rbv_api.deleteRecord("employee", employeeIDsBefore[i]);
		}
	}
} else if(employeeIDsBefore.length && !employeeIDsAfter.length) {
	for(var i = 0; i < employeeIDsBefore.length; i += 1) {
		rbv_api.deleteRecord("employee", employeeIDsBefore[i]);
	}
}

Posted by Orchid Corpin on 10-Sep-2014 10:58

Hi matman,

Well you are right, [] do it better than new Array() maybe i should replace my coding style in arrays with [] too :D
When returning "" {!R1234567} returns the first ID, rather than all IDs. If using update field value this sometimes varies on the return type of the trigger formula.
Thank you.

Regards,
Orchid

This thread is closed