Adding Lookups
Lookups are read-only mechanisms which queries the service to get a list of values that appear as a drop-down list. Lookups can be based on other items of information already provided on the form. Using Lookups eliminates the need to manually enter or to remember the values associated with your third-party account resources, while configuring an Action or a Trigger.
Use Lookups in Actions and Triggers. To display many items, lookups uses a paging mechanism.
Lookups support initial data filtering. For example, when you type text in the lookup field and click the arrow a list of values containing the text appears.
Unlike other artifacts lookups are not versioned externally. Each lookup call is a function in the lookup artifact. As a result, there is one lookup artifact per connector.
For example, there is a lookup action in the figure that follows. The lookup fetches the user's email from Gmail and these values appear in the Message ID as an input. This is possible because the schema specifies that a lookup can be used for this field.
To implement the get-mail-details action, you need the id of the email account. The lookup script uses the authentication of your Gmail account to search all the emails in your account. The list then appears on the Action form, and you can select the appropriate id as a Lookup.
To create a new lookup, do the following:
1. From the command prompt, execute the following commands:
a. cd <user project root directory>
b. flow add lookup
The name of the lookup is the name of the connector and it is created in the lookups folder in the project directory.
The following options are available for the command.
Options | Description | Data Type |
---|
--version | Displays the version number. | [boolean] |
--help | Displays the help | [boolean] |
--parentDir, -d | The parent directory for the project. | [default: “.”] |
--logLevel, -1 | Sets the log level. | [default: “info”] |
2. Update the properties in the index.js file.
A Lookup JavaScript should export a single JavaScript object. The object can contain any number of methods. The index.js file has the following structure.
function(input, options, output){
return}
| The code might be different if the external service uses a Connection instead of an OAuth. |
The options object provides a number of utility methods that are required for use in lookups.
validateDependencies(input.<property name>)—Check that the input contains the given property.
options.getAccessToken(input.auth, function(err, data) { }): Fetch the access token from the server. input.auth contains a UID that is used to fetch the access token. options.getConnection(input.connection, function(err, data){ }) : Fetch the connection corresponding to the UID contained in the connection property.
The following table describes how the arguments are used.
Argument | Usage |
---|
input | Contains the dependencies configured on the lookup. |
options | Provides utility methods to fetch the authentication mechanism, Connection or Access token and to enable paging support. |
output | Callback that needs to be invoked to return results back to ThingWorx Flow. It follows the node’s error-first convention. The result must be an array of JSON objects. Typically, they are id and value pairs. Additional fields may be added if the dynamic schema is added. For more information, refer to the section Dynamic Schema Injection. The result must be passed to the callback (output function) and it has to be an array of JSON objects containing the id and the value. The results should be in the following format: { [ {"id":"id1","value":"value1"}, {"id":"id2","value":"value2"}, ], “next_page”: true } |
For an example on adding Lookups, refer to
Tutorial B.
Dynamic Schema Injection
If there is a fixed input and output schema for an action, it creates a limitation when building actions that are rich in functionality. The input and output schema for an action can be updated based on user choices when loading a lookup or when selecting a value from the lookup. Consequently, the form is updated to match the updated input schema retaining the current values. Also, the output fields available for mapping on the next action are updated to match the updated output schema.
Updates to the input and output schema for an action can be done on the lookup result processing interface.
You can inject the dynamic schema while returning the results of the lookup or you can add another function to the lookup through the onSelect attribute (for selected option). When injected at the time of lookup loading, the dynamic schema injection needs the schema for all the lookup values.
| Multilevel injection, using two consecutive lookups, is possible for some things. Multilevel injection can append with restrictions,but it cannot remove. |
The way to add input schema that the form displays is to use the schema, parent, and append attributes on the resulting JSON for the lookup next to id and value. Similarly, use outSchema, outAppend and outParent to add output schema, which appears as the output schema of the action when the connected action is opened. Typically, the append or outAppend and parent or outParent are used together, when the schema provided is appended to the parent indicated to extend the properties. If append is not used, the schema is replaced with the newly added schema.
The parent or outParent attribute is the id of the schema element (must be of type object) for the respective schema. If of the parent or outParent attribute is absent, the default context for the update is the root of the respective schema. The update of the schema occures within the scope of the parent or outParent object, by merging or replacing in absence of append/outAppend, the properties that are provided in the injection schema with the existing properties.
You can also use the userSelected attribute on the output schema being injected. It is used to inject a default schema with value false, and replace it with a subset, value true, when you select options on the form. If the userSelected = true attributes are removed when an array element of the form is deleted, the schema reverts to the default value.
For example, for the OData connector, set the input and output injection schema as shown in the following figure:
The input injection schema for OData is as follows:
"schema": {
"Properties": {
"type": "object",
"title": "Properties",
"properties": {
"AirlineCode": {
"type": "string",
"title": "AirlineCode",
"minLength": 1
},
"Name": {
"type": "string",
"title": "Name",
"minLength": 1
}
}
}
}
The output injection schema for OData is as follows:
"outSchema": {
"properties": {
"Airlines": {
"type": "array",
"title": "Airlines",
"displayTitle": "Airlines",
"items": {
"type": "object",
"properties": {
"AirlineCode": {
"title": "AirlineCode",
"type": "string",
"userSelected": false
},
"Name": {
"title": "Name",
"type": "string",
"userSelected": false,
"visible": true
}
}
}
}
}
}
As suggested in the example above, a few parameters can be fixed on the mapping user interface in the dynamically injected output schema by setting the following property—visible = true.
To internationalize the input and output dynamic schema, refer to the section
Internationalization Support for Connectors.
Paging
Lookups support paging , i.e. the ability to produce many pages of result. Every invocation produces a single page of result. On the UI the page can be retrieved by clicking on “More results” in the list. The input and the options objects contains methods and properties to deal with paging.
• options.getNextPage(boolean)—Used in paging to return the URL to fetch the next page. This URL must be set on the “next_page” property of the result object for paging to work correctly. If no more pages are to be returned set this property to false.
• options.maxResults—Used with paging to get the maximum number of results to return at a time.
• input.page—The current page number.
• input.searchById—Search by id.
• input.searchByValue— Search by value.
Search by Id and Value are available if the lookup has the searchable flag set to true. For an example of lookup, refer to the sections above. These properties help to narrow the search by searching the target system for items that match the Id or value.
| The id and value may refer to different fields in the target system. |