Integration Toolkit Solutions Wiki

By popular request, I've created this topic to be used in wiki mode for collaborative generation of solutions to particular problems. To keep this neat, please follow these guidelines:

  • New problems seeking solutions should be posted as replies, and the discussion of that problem kept within that comment, wiki-style. A one-line summary should be added to this topic starter, with an embedded link (not on its own line). After posting, be sure to convert the comment to operate in wiki mode.

  • Use the "Hide Details" tool to keep the one comment neat. In particular, code blocks belong inside the details.

  • Create a "uses" details section at the end of a problem/solution comment where you deep link into the public module documentation for each function or feature used in the solution. Consider also deep linking into the IA manual, too.

Public Integration Toolkit Overview

Ignition Native Scripting Functions, By Scope

Ignition Native Expression Functions

Use the Integration Toolkit wiki - setup discussion thread for discussion about this wiki.

{ Please add, within reason, to these best practices. }

Problem Index

Link your comments below here, as bullets, with a one-line description as the link text.

12 Likes

Perspective Table Data and Columns Config from Datasets

When using the JSON return format in a Named Query, the column order and original column datatypes are lost. You can move a Named Query binding to a custom property of the component or view, then use this simple iteration expression to deliver the jsonified content to the table:

Binding on props.data
forEach(
	{path.to.source.dataset.prop},
	asMap(it())
)
Features employed
  • Iterables General behavior of all iterators.
  • forEach() Loops through the dataset, calling the nested expression with one row at a time.
  • it() Delivers the one row in dataset format (same column names and types as the source).
  • asMap() Converts the first row of the dataset it is given into a mapping (dictionary) of key-value pairs.
2 Likes

Creating a custom property dataset using a temporary binding

There isn't a built-in method to create a dataset in a Perspective custom property. Creating an Expression Binding with this script will generate one. The binding can then be removed leaving the dataset.

Expression binding on custom property
unionAll(
	asMap(
		"someDate", "date",
		"someBool", "B",
		"someInt", "I",
		"someString", "str"
	),
	asList() // No row data.
)
/* Returns
"#NAMES"
"someDate","someBool","someInt","someString"
"#TYPES"
"date","B","I","str"
"#ROWS","0"
*/
Features employed
  • unionAll() Assembles an output dataset from scratch, using the given column names and types (internally via a DatasetBuilder), performing a UNION ALL with each row source.
  • asList() unconditionally assembles all of its arguments into a List.

You really only need to create one column with the binding and then modify the result with the Dataset Editor. (Click the icon to the right of the Dataset [...].)

1 Like

Merging lists into a single list of objects

How would I merge multiple lists into a single list of objects/dicts?
e.g.

a = [1,2,3,4]
b = ['a','b','c','d']
c = {'a': 1, 'b': 2, ...} # create this one

Iterate over one while picking from the other. But use transform() to snapshot for use within the iterator.

Emulation of dict(zip(b, a))
transform(
	{path.to.list.a},
	asMap(
		forEach(
			{path.to.list.b},
			it(),
			value()[idx()]
		)
	)
)

Note that the toolkit's asPairs() function works like python's .extend(), not zip().

You can shuffle the order of operations to get various output types.

Features Employed
  • transform() Makes a snapshot of list a.
  • Iterables General behavior of all iterators.
  • forEach() Loops through the list of keys, calling the nested expressions with one key at a time, yielding a list of pairs.
  • it() Delivers the key from list b.
  • value() Retrieves the snapshot of list a.
  • idx() Retrieves the zero-based loop index to use as a subscript into list a.
  • asMap() Creates a map of the list of key-value pairs.

{ Someone forgot to make their question a wiki.... }

4 Likes

Filtering datasets and emulating the IN operator

Many times you want to filter a dataset where a columns value is equal to one of any item in a list. In SQL this is possible by utilizing the 'IN' operator. However, outside of using a QueryString parameter, due to the way that Named Query parameters work you can not supply a List of values.

If you create a custom property to hold the raw data set from the named query, then you can use a simple expression binding to filter the dataset further in a similar manner to that seen when using the SQL IN operator.

Filtering by a List of Values
unionAll(
    columnsOf({path.to.raw.data}),
    forEach(
        {path.to.List},
        where(
            {path.to.raw.data},
            it()['ColumnToFilter'] = it(1)
        )
    )
)

Note that for filtering by a single value, only the where() expression is needed.

Filtering by a Single Value
where(
    {path.to.raw.data},
    it()['ColumnToFilter'] = {path.to.filter.value}
)
Features employed
  • Iterables General behavior of all iterators.
  • unionAll() Assembles the list of filtered rows sources into a new filtered dataset.
  • columnsOf() Returns an ordered map of the column names versus column type class names (as strings).
  • forEach() Loops through the list of items, for comparison in the conditional argument of the where() expression.
  • where() Prunes the source data according to supplied conditional expressions.
  • it([depth]) Delivers the current iterations value based on the depth argument supplied.

Note that for static lists, the asList() expression can be used in place of {path.to.list}