Scripting in Settings > staticMap > exportSelect > Saved values not showing

G'day all,

I've been following the posts about how to use a forminit script to query NetSuite to help populate settings.

Everything works as expected when creating a single exportSelect but when creating a staticMap with an exportSelect, in the UI after a save of the settings, the exportSelect field continues to show "Please Select". Any Idea what I have done wrong?

(For reference, the values are saved and are accessible, they are just not seen in the Settings UI.)

Example code: 

function formInit(options) {
let form = options.resource.settingsForm.form;
if (!form) form = { fieldMap: {}, layout: { fields: [] } };

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

form.fieldMap.ReasonMapping = {
  "id": "ReasonMapping",
  "name": "ReasonMapping",
  "type": "staticMap",
  "label": "Map 3PL reason codes to NetSuite Reasons",
  "columns": [
    {
      "id": "3plReasonCode",
      "label": "3PL Reason",
      "type": "input",
    },
    {
      "id": "netsuiteReason",
      "name": "NetSuite Reason",
      "type": "exportSelect",
      "refresh": false,
      "resource": {
        "virtual": {
          "_connectionId": connectionId,
          "asynchronous": true,
          "netsuite": {
            "type": "restlet",
            "skipGrouping": true,
            "restlet": {
              "recordType": "customlist_rma_reason",
              "columns": [
                {
                  "name": "name",
                  "label": "label"
                },
                {
                  "name": "internalId",
                  "label": "value"
                }
              ]
            }
          }
        }
      }
    },
  ]
};

form.layout.fields.push('ReasonMapping');

options.resource.settingsForm.form = form;
options.resource.settings.ReasonMapping = form;

return form;

}

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

0

Comments

7 comments
Date Votes
  • Nathan Tegel it doesn't look like you're following the correct JSON structure for staticMap: https://docs.celigo.com/hc/en-us/articles/360059205112-Common-form-fields#type_staticMap

    0
  • Thanks Tyler Lamparter

    A colleague and I independently went through several examples today trying to get this to work and we were both not successful in getting this going.

    What we tried was, going back to a simple JSON example:

    I don't know if this helps, but when you click save, you can see the form being recreated, and in the blink of an eye it appears the correct values are set until it reverts to "Please Select".

    Any assistance would be greatly appreciated (we've had to put in a text-only staticMap until we can get this resolved).

    Example JSON:

    {
     "fieldMap": {
       "salesforceAccountType_map_netsuiteCustomerStageAndStatus": {
         "optionsMap": [
           {
             "id": "netsuiteLocation",
             "name": "NetSuite Location",
             "type": "exportSelect",
             "resource": {
               "virtual": {
                 "name": "Lookup",
                 "_connectionId": "65cc3d28f44fxxxxxx7cd43",
                 "apiIdentifier": "ea7xxxx679",
                 "asynchronous": true,
                 "oneToMany": false,
                 "sandbox": true,
                 "netsuite": {
                   "type": "restlet",
                   "skipGrouping": true,
                   "statsOnly": false,
                   "restlet": {
                     "recordType": "location",
                     "searchId": "2496",
                     "useSS2Restlets": false
                   },
                   "distributed": {
                     "useSS2Framework": false
                   }
                 },
                 "distributed": {
                   "disabled": false
                 },
                 "adaptorType": "NetSuiteExport"
               }
             }
           },
           {
             "id": "netsuiteCustomerStage",
             "label": "NetSuite Customer Stage",
             "required": true,
             "type": "select",
             "options": [
               {
                 "value": "lead",
                 "label": "Lead"
               },
               {
                 "value": "prospect",
                 "label": "Prospect"
               },
               {
                 "value": "customer",
                 "label": "Customer"
               }
             ]
           },
           {
             "id": "netsuiteCustomerStatus",
             "label": "NetSuite Customer Status",
             "required": false,
             "type": "select",
             "options": [
               {
                 "value": "6",
                 "label": "Unqualified"
               },
               {
                 "value": "7",
                 "label": "Qualified Lead"
               },
               {
                 "value": "8",
                 "label": "In Discussion"
               },
               {
                 "value": "9",
                 "label": "Identified Decision Makers"
               },
               {
                 "value": "10",
                 "label": "Proposal"
               },
               {
                 "value": "11",
                 "label": "In Negotiation"
               },
               {
                 "value": "12",
                 "label": "Purchasing"
               },
               {
                 "value": "13",
                 "label": "Closed Won"
               },
               {
                 "value": "14",
                 "label": "Closed Lost"
               },
               {
                 "value": "15",
                 "label": "Renewal"
               },
               {
                 "value": "16",
                 "label": "Lost Customer"
               },
               {
                 "value": "17",
                 "label": "Qualified Prospect"
               }
             ]
           }
         ],
         "allowFailures": false,
         "hideLookupAllowFailures": true,
         "title": "Map Salesforce Account Type to NetSuite Customer Stage and Status",
         "tooltip": "",
         "name": "salesforceAccountType_map_netsuiteCustomerStageAndStatus",
         "type": "staticMap"
       }
     },
     "layout": {
       "fields": [
         "salesforceAccountType_map_netsuiteCustomerStageAndStatus"
       ]
     }
    }

    0
  • Nathan Tegel I discussed internally and having refreshable fields under optionsMap is not currently supported even though it currently semi-works. We will have to take this up as an enhancement request and prioritize it for a future release.

    With that being said, after saving, the data does actually save, but when coming back to the form, the previously selected values don't display for your refreshed column.

    An alternative would be to use a form script that populates the optionsMap. Doing that should work just fine.

    0
  • Thanks Tyler Lamparter

    We are keen to be able to use this feature, we have a few projects in the pipeline where doing this is going to make the build process faster!

    0
  • Nathan Tegel with a little elbow grease on a form script, you can get this to go. Here is an example:

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

    class Form {
        // { fieldMap: {}, layout: { fields: [] } }
        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;
        }

        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();
        // reference: https://docs.celigo.com/hc/en-us/articles/360059205112-Common-form-fields
        // deconstruct form to make access to fieldMap for prop assignment simpler
        let { fieldMap } = form;

        //create field for staticMap with options map
        fieldMap.multiMap = new Field('multiMap','multiMap', 'Multi mapping', 'staticMap');
        fieldMap.multiMap.addStaticMapOptionsMap();
        
        //gather netsuite locations
        fieldMap.netsuiteLocation = new Field('netsuiteLocation','netsuiteLocation', 'NetSuite Location', 'select');
        let nsLocations = getNetSuiteLocations();
        for (let s of nsLocations) {
          fieldMap.netsuiteLocation.addOption(s.label,s.value,true);
        }
        fieldMap.multiMap.optionsMap.push(fieldMap.netsuiteLocation);
        
        //gather stages
        fieldMap.customerStage = new Field('customerStage','customerStage', 'NetSuite Customer Stage', 'select');
        for (let s of customerStageOptions) {
          fieldMap.customerStage.addOption(s.label,s.value,true);
        }
        fieldMap.multiMap.optionsMap.push(fieldMap.customerStage);
        
        //gather statuses
        fieldMap.customerStatus = new Field('customerStatus','customerStatus', 'NetSuite Customer Status', 'select');
        for (let s of customerStatusOptions) {
          fieldMap.customerStatus.addOption(s.label,s.value,true);
        }
        fieldMap.multiMap.optionsMap.push(fieldMap.customerStatus);

        //set the layout for the form
        form.fields(...['multiMap']);

        // wrap up by assigning form to options.resource.settingsForm prop; return the form as well
        options.resource.settingsForm.form = form;
        return form;
    }


    var customerStageOptions = [
                      {
                        "value": "lead",
                        "label": "Lead"
                      },
                      {
                        "value": "prospect",
                        "label": "Prospect"
                      },
                      {
                        "value": "customer",
                        "label": "Customer"
                      }
                    ];
                    
    var customerStatusOptions = [
                      {
                        "value": "6",
                        "label": "Unqualified"
                      },
                      {
                        "value": "7",
                        "label": "Qualified Lead"
                      },
                      {
                        "value": "8",
                        "label": "In Discussion"
                      },
                      {
                        "value": "9",
                        "label": "Identified Decision Makers"
                      },
                      {
                        "value": "10",
                        "label": "Proposal"
                      },
                      {
                        "value": "11",
                        "label": "In Negotiation"
                      },
                      {
                        "value": "12",
                        "label": "Purchasing"
                      },
                      {
                        "value": "13",
                        "label": "Closed Won"
                      },
                      {
                        "value": "14",
                        "label": "Closed Lost"
                      },
                      {
                        "value": "15",
                        "label": "Renewal"
                      },
                      {
                        "value": "16",
                        "label": "Lost Customer"
                      },
                      {
                        "value": "17",
                        "label": "Qualified Prospect"
                      }
                    ];
                    
    function getNetSuiteLocations() {
        return exports.runVirtual({
            "export": {
                  "name": "Lookup",
                  "_connectionId": "626c245268e40e1032975cfe",
                  "asynchronous": true,
                  "oneToMany": false,
                  "netsuite": {
                    "type": "restlet",
                    "skipGrouping": true,
                    "statsOnly": false,
                    "restlet": {
                      "recordType": "location",
                      "searchId": "3369",
                      "useSS2Restlets": false
                    },
                    "distributed": {
                      "useSS2Framework": false
                    }
                  },
                  "distributed": {
                    "disabled": false
                  },
                  "adaptorType": "NetSuiteExport"
                }
        }).data;
    }

    0
  • Thanks Tyler Lamparter, we have been able to get that working!

    The only odd thing is you don't seem to be able to test it in the Form Builder. We get the following error:

    Message: Access restricted
    Location: integrator-api/index.js:211
    Stack: Error: Access restricted
        at throwResponseBodyAsError (integrator-api/index.js:195:21)
        at runVirtualExport (integrator-api/index.js:355:3)

    0
  • Nathan Tegel -Currently, scripts containing integrator API calls cannot be previewed; they must be saved first to verify functionality. We appreciate your feedback and will use it to improve the preview capabilities for scripts using integrator APIs.

    0

Please sign in to leave a comment.

 

Didn't find what you were looking for?

New post