How to access target onAfter script in IntegrationHub ETL definition
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi Devs,
I am having issue accessing the target in the ETL defintion in an IntegrationHub import. I am trying to update the records on the target in an onAfter script. I cannot access the target object, when I log it, the target returns undefined and null, however the target record is populated from the import set.
Create Extract Transform Load (ETL) definitions - I have also tried to stringify the target object, but I still cannot update the target. and target.update() shows that the function is not defined in the logs.
This is my current script, it is not updating the target records.
(function onAfter(source, target, importLog) {
var userGR = new GlideRecord('sys_user');
userGR.addQuery('email', source.email);
userGR.query();
if (userGR.next()) {
target.user = userGR.sys_id;
target.last_synced = new GlideDateTime();
gs.info('onAfter email=' + source.email +
' | target=' + target +
' | user =' + userGR.sys_id);
}
})(source, target, importLog);error when trying to use target.update();
com.glide.script.RhinoEcmaError: Cannot find function update in object [object Object].
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hey @zynsn,
This trips a lot of folks up the first time. In IntegrationHub ETL, the onAfter(source, target, importLog) callback passes target as a plain JS object, not a GlideRecord. That’s why target.update() isn’t there and why logging it often shows [object Object] or undefined/null depending on timing.
- In onBefore/onTransform, you can safely set target.some_field = ... to influence what gets written.
- In onAfter, the insert/update has already happened. If you need to make additional changes after the ETL write, you’ll want to load the target record as a real GlideRecord using its table + sys_id, then call update().
Below is a small pattern you can drop in. It looks up the user by email, loads the target record, and updates two fields:
(function onAfter(source, target, importLog) {
// Try to get table + sys_id from importLog first; fall back to target
var targetTable =
(importLog && importLog.targetTable) ||
(importLog && importLog.getTargetTableName && importLog.getTargetTableName()) ||
target.table || target._table;
var targetSysId =
(importLog && importLog.targetSysId) ||
(importLog && importLog.getTargetRecordSysId && importLog.getTargetRecordSysId()) ||
target.sys_id || target._sys_id;
if (!targetTable || !targetSysId) {
gs.warn('ETL onAfter: missing target identifiers. table=' + targetTable +
' sys_id=' + targetSysId + ' target=' + JSON.stringify(target));
return;
}
// Find user by email from the source row
var userGR = new GlideRecord('sys_user');
userGR.addQuery('email', source.email);
userGR.query();
if (!userGR.next()) {
gs.info('ETL onAfter: no user found for email=' + source.email);
return;
}
// Load the actual target record and update it
var gr = new GlideRecord(targetTable);
if (!gr.get(targetSysId)) {
gs.warn('ETL onAfter: could not load target record ' + targetSysId + ' on ' + targetTable);
return;
}
// Adjust these field names to match your table (e.g., 'u_user', 'assigned_to')
gr.setValue('user', userGR.getUniqueValue());
// If 'last_synced' is a date/time field, this works well:
gr.setValue('last_synced', gs.nowDateTime());
gr.update();
gs.info('ETL onAfter: updated ' + targetTable + ' ' + targetSysId +
' user=' + gr.getValue('user'));
})(source, target, importLog);A couple of quick sanity checks:
- Make sure the target table really has fields named user and last_synced. If they’re custom, use your actual column names (u_user, etc.).
- If your only goal is to set those values during the initial write, consider doing it in onBefore instead—fewer DB writes and simpler logic.
- For date/time, either use gs.nowDateTime() or new GlideDateTime().getValue(); assigning the raw object directly to a string field won’t stick.
If you share your exact target table name and column names, I can tweak the snippet to be plug‑and‑play for your setup.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi,
The 'target' variable isn't a singular GlideRecord, it's a object containing an array of objects depending on what records you're inserting/updating. From memory, the object is a java object, and doesn't log out property. However you can use script tracer, and add break points in your script to then use the script debugger to see the value/structure of the object
