# Automation Professionals' Integration Toolkit Module

**URL:** <https://forum.inductiveautomation.com/t/automation-professionals-integration-toolkit-module/74934>\
**Category:** 3rd Party Modules\
**Tags:** ignition81, ignition83, perspective, vision, scripting\
**Created:** [June 13, 2023, 12:42am UTC](https://forum.inductiveautomation.com/t/automation-professionals-integration-toolkit-module/74934 "2023-06-13T00:42:35Z")\
**Posts on this page:** 1\
**Showing post:** 62

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 14, 2023, 4:02pm UTC](https://forum.inductiveautomation.com/t/automation-professionals-integration-toolkit-module/74934/62 "2023-08-14T16:02:21Z")

</div>

Another new feature to report. 😄 After I realized I could coerce my iterator functions into executing a common sub-expression once, as shown here:

> [@Expression: get 3rd to last element of split(..) result](https://forum.inductiveautomation.com/t/expression-get-3rd-to-last-element-of-split-result/15159/12):
>
> I've never been real happy with how expressions deal with common sub-expressions. That is, not happy at all. The impetus to find a solution isn't there in Perspective, because you can put such expressions ahead of a transform so they will only be executed once. (And if you have more than one, my new asList() expression can bundle multiple such into a single value.) But expression tags and Vision UI bindings do not have transforms. frowning_face I realized while reading this topic that I'…

I decided it was too lame. And would greatly complicate any other use of `it()` in the expression. And doesn't really track well with the origin of the idea, which was the use of Perspective transforms to ensure a common expression executed just once.

With this update, the expression:

```auto
forEach(
	asList(
		split({path.to.some.string}, '/')
	),
	it()[len(it())-1, 0]
)[0]

```

can now be written:

```auto
transform(
	split({path.to.some.string}, '/'),
	value()[len(value())-1, 0]
)

```

Which is really, really similar to a Perspective expression binding of:

```auto
split({path.to.some.string}, '/')

```

followed by the expression transform:

```auto
{value}[len({value})-1, 0]

```

So, if you have a value expression and an expression transform in Perspective, you can now use that combination elsewhere. Just replace `{value}` with `value()`. Specifically, it brings the equivalent of Perspective transforms to:

- Expression tags (both gateway and Vision client tags),

- Vision component bindings,

- Identity Provider attribute mapping,

- Alarm pipeline expression blocks, and

- SFC property expressions.

If necessary, you can use `objectScript()` (or `runScript()`) to emulate a script transform. If you are following the best practice of have all script transforms be a one-line callout to a project script, the conversion is trivial.

Also, this function can be nested to emulate multiple transforms. If necessary, the `depth` argument to `value()` can be used to reach back to a prior stage's result. The nesting of `transform()` is independent of any use of the iterator functions and does not impact the `it()` hierarchy depth at all.

For Ignition v8.1+, as usual: ~~v2.0.11.232261523~~

{Unlike the iteration functions, where expressions involving `it()` cannot also include connectable functions like `now()` or `tag()`, `transform()` doesn't impose any such conditions on expressions involving `value()`.}

---

_[View the full topic](https://forum.inductiveautomation.com/t/automation-professionals-integration-toolkit-module/74934)._
