Settings Script Form

Hi,

I’m using a Scripted Form in the Settings of my Integration. The issue I’m having is that it persists old data I’ve entered in the form but have replaced with new entries. I’m unable to remove the unwanted entries from the Script input.

Example of my Script input with double entries for nsLocation 143:

{
    "nsLocation": "143",
    "shopLocation": "85947351269"
},
{
    "nsLocation": "143",
    "shopLocation": "85947351269",
    "locationMetaobjectId": "125842620645"
}

The first entry is old, it’s not displaying on the form UI. The correct one is the second one.

Is there any way the stored data is only what’s in the form UI?

Thanks,

Emily

I believe the only way to persist data into the settings object is by entering it through the UI (form) and then clicking "Save". So editing the data values in the script in the settings alone won’t actually store or update any data — it only defines how the form appears.

You need to use the removeInvalidValues property: https://docs.celigo.com/hc/en-us/articles/360059205112-Common-form-fields#UUID-6ce95fef-1430-cbc6-4dfe-e5f0285a0f8e_id_360059205112_id_type-removevalues.

Hi Tyler, thanks for your response.

It says that the removeInvalidValues property can only be used when "type": "multiselect".
In my case, my field map is made up of a staticMap field that sources NetSuite Locations, and then 2 text’fields for setting the Shopify Location ID and Metaobject ID for the given Location.

It appears that the only option for now is to remove all the entries and re-enter them.

Regards,

Emily

Gotcha, I'll discuss with @sreevaniamara and see if we can extend the removeInvalidValues property to other field types. Could you share your form script or output of it just to make sure we're tackling the right thing?

Thanks Tyler.

Settings script:

import {
connections,
integrations,
exports,
imports,
flows,
request
} from 'integrator-api';

class Form {
constructor() {
this.fieldMap = {};
this.layout = {};
this.layout.containers = 
;
}

fields(...fields) {
this.layout.fields = fields;
}

container(type, label, ...fields) {
this.layout.containers.push({
type: type,
containers: [{
label: label,
fields: fields
}]
});
}

column(label, ...fields) {
this.layout.type = 'column';
this.layout.containers.push({
label: label,
fields: fields
});
}
}

class Field {
constructor(id, name, label, type) {
this.id = id;
this.name = name;
this.label = label;
this.type = type;
this.removeInvalidValues();
}

isRequired() {
this.required = true;
}

removeInvalidValues() {
this.removeInvalidValues = true;
}

canBeDeleted() {
this.showDelete = true;
}

isMultiline() {
this.multiline = true;
}

description(description) {
this.description = description;
}

help(helpText) {
this.helpText = helpText;
}

typeOfInput(type) {
this.inputType = type;
}

default(defaultValue) {
this.defaultValue = defaultValue;
}

delimiter(delimiter) {
this.delimiter = delimiter;
}

keyNamePlaceholder(keyName) {
this.keyName = keyName;
}

valueNamePlaceholder(valueName) {
this.valueName = valueName;
}

mode(mode) {
this.mode = mode;
}

addOption(arg1, arg2, excludeItems) {
if (!excludeItems) {
if (!this.hasOwnProperty('options')) {
this.options = [{
items: 

}];
}

  if (arg2) {
    this.options[0].items.push({
      label: arg1,
      value: arg2
    });
  } else {
    this.options[0].items.push(arg1);
  }
} else {
  if (!this.hasOwnProperty('options')) {
    this.options = [];
  }

  if (arg2) {
    this.options.push({
      label: arg1,
      value: arg2
    });
  } else {
    this.options.push(arg1);
  }
}

}

addStaticMapOptions(keyName, keyLabel, keyOptions, valueName, valueLabel, valueOptions) {
this.keyName = keyName;
this.keyLabel = keyLabel;
this.keyOptions = keyOptions;
this.valueName = valueName;
this.valueLabel = valueLabel;
this.valueOptions = valueOptions;
}

addStaticMapOptionsMap() {
this.optionsMap = 
;
this.allowFailures = false;
this.hideLookupAllowFailures = true;
}
}

function formInit(options) {
let form = new Form();
let { fieldMap, layout } = form;

var connectionId = getConnectionIdByAlias(options, 'netsuiteconnectionalias');

// Header Discount Item
// fieldMap.netsuiteHeaderDiscountItem = new Field('nsHeaderDiscountItem', 'nsHeaderDiscountItem', 'Header Discount Item', 'select');
// let nsItem = getNetSuiteValues(connectionId, 'discountitem', 'itemid', 'internalid');
// for (let s of nsItem) {
//   fieldMap.netsuiteHeaderDiscountItem.addOption(s.label, s.value, false);
// }

// Shopify Store ID
fieldMap.shopifyStore = new Field(
'shopifyStore',
'shopifyStore',
'Shopify Store ID',
'text'
);

// Size Metafield
fieldMap.sizeGuide = new Field(
'sizeGuide',
'sizeGuide',
'Size Guide Metaobject ID',
'text'
);

// Location Mapping
fieldMap.locationMap = new Field('nsLocationToShopify', 'nsLocationToShopify', 'Location Mapping', 'staticMap');
fieldMap.locationMap.addStaticMapOptionsMap();

fieldMap.netsuiteLocation = new Field('nsLocation', 'nsLocation', 'NetSuite Location', 'select');
let nsLocations = getNetSuiteValues(connectionId, 'location', 'name', 'internalid');
for (let s of nsLocations) {
fieldMap.netsuiteLocation.addOption(s.label, s.value, true);
}
fieldMap.locationMap.optionsMap.push(fieldMap.netsuiteLocation);

fieldMap.shopifyLocation = new Field('shopLocation', 'shopLocation', 'Shopify Location', 'text');

// Location Metaobject ID
fieldMap.locationMetaobjectId = new Field(
'locationMetaobjectId',
'locationMetaobjectId',
'Location Metaobject ID',
'text'
);

fieldMap.locationMap.optionsMap.push(fieldMap.shopifyLocation);
fieldMap.locationMap.optionsMap.push(fieldMap.locationMetaobjectId);

form.fields(
'shopifyStore',
'sizeGuide',
...['locationMap']
);

options.resource.settingsForm.form = form;
return form;
}

// Remove duplicate location mappings
function scriptInput(options) {
if (
options.resource &&
options.resource.settings &&
options.resource.settings.nsLocationToShopify &&
options.resource.settings.nsLocationToShopify.value
) {

const seen = new Set();

options.resource.settings.nsLocationToShopify.value =
  options.resource.settings.nsLocationToShopify.value.filter(function(row) {
    const key = row.nsLocation;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });

}

return options;
}

function getNetSuiteValues(connectionId, recordType, name, value) {
return exports.runVirtual({
'export': {
'name': 'Lookup',
'_connectionId': connectionId,
'asynchronous': true,
'oneToMany': false,
'netsuite': {
'type': 'restlet',
'skipGrouping': true,
'statsOnly': false,
'restlet': {
'recordType': recordType,
'useSS2Restlets': true,
'columns': [
{
'name': name,
'label': 'label'
},
{
'name': value,
'label': 'value'
}
]
},
'distributed': {
'useSS2Framework': false
}
},
'distributed': {
'disabled': false
},
'adaptorType': 'NetSuiteExport'
}
}).data;
}

function getConnectionIdByAlias(data, aliasToFind) {
let resource = data.resource;
if (!resource.aliases) resource = data.parentResource;
if (!resource.aliases) resource = data.grandParentResource;
if (!resource.aliases) return null;
const aliasEntry = resource.aliases.find(alias => alias.alias === aliasToFind);
return aliasEntry ? aliasEntry._connectionId : null;
}

The Script input holds duplicate entries for some of the Locations, although they don’t show in the UI.

Hi Tyler! Just checking if you’ve had a chance to take a look at the code and know of any way around it to avoid the issue?

Cheers,

Emily

My only current thought is to use a preSave script to fetch what options are valid, compare that against the settings, then remove settings entries that aren't valid. We're checking on the feasibility to bring removeInvalidValues to this field type as well, but I don't have any timeline on that.
https://docs.celigo.com/hc/en-us/articles/27359514088859-Pre-save-script

1 Like

Thanks!