# How to reliably call a function after \`refreshBinding\`

**URL:** <https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871>\
**Category:** Ignition\
**Tags:** ignition81, perspective, scripting\
**Created:** [October 29, 2024, 4:45am UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871 "2024-10-29T04:45:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [October 29, 2024, 4:45am UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871/1 "2024-10-29T04:45:28Z")

</div>

Hi, I'm trying to wrangle the Perspective Tree component to do what I want it to, but I'm having the darndest time, so here I am back on the Forums, complaining.

Basically, what I'm trying to do is to pre-select a node in the Tree `onStartup` (view). What is happening that is preventing me from accomplishing this successfully is that I do a call to refresh the `items` prop of the Tree right before I get the item to select.

Something like

```python
...
self.path.to.tree.refreshBinding('props.items')
items = self.props.items[0].items
...

```

I get an error on the second line which says `Error: NoneType object is unsubscriptable` - how I interpret this is that this happens because the `props.items` are queried from a database, so there is a slight delay in the refresh of that property, but the method call to refresh binding seems to happen asynchronously, so that the second line (`items = self.props.items`) fails because the `props.items` property is still `null`.

Just for completeness, I added a "Debug" button on my view that essentially does the exact same thing and I get the behavior I want. When I do do that, my best guess is that `props.items` is already populated, so I can execute the script on a button however many times I want, even though I'm refreshing the binding, just like I am on the `onStartup` view script.

What I would like to do is to only call the `items = self.props.items[0].items` line after the binding has been refreshed and the property is populated - is there a good way to do this?

---

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [October 29, 2024, 4:55am UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871/2 "2024-10-29T04:55:00Z")

</div>

Just to follow up on this, I added a `time.sleep(2)` call between the `refreshBinding` call and the `items` assignment and this fixed my issue, so I'm confident this is happening because the `props.items` property is still null when the assignment happens.

How do I fix this in a good way? I refuse to throw a change script on the `props.items` property that will select an item for me when the `previousValue` was null - I'm moving away from screen design using this paradigm heavily because it is absolute hell trying to troubleshoot / debug things [unless, of course, I can be persuaded otherwise]. IMHO, property change scripts should be used very intentionally and sparingly.

---

<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:** [October 29, 2024, 10:58am UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871/3 "2024-10-29T10:58:01Z")

</div>

> [@YF129701](#):
>
> I refuse to throw a change script on the `props.items` property

Well, that is the point that gets the notice when the item objects arrive. The change script is the right way to execute more script actions after the refresh completes.

Make it a one-liner that delegates to a project library script to aid troubleshooting. (Do this everywhere, really.)

---

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [October 29, 2024, 2:43pm UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871/4 "2024-10-29T14:43:42Z")

</div>

I spoke with my friend who seems to always have the best answers when I'm stuck. What I ended up doing to avoid the change script was to take the runScript binding I had on the Tree `props.items` and ran that within my script, then did assignment to the Tree's `props.items`, then I was able to get the `items` variable to work as it should.

So, I went from

```python
self.refreshBinding('props.data') # binding is a runScript expression to my.shared.script(p1,p2)
items = self.props.items[0].items
...

```

to

```python
newTreeItems = my.shared.script(p1, p2) # generates tree instances
self.props.items = newTreeItems

items = self.props.items[0].items
...

```

This has worked reliably ever since I implemented it, so this is what I'll keep.

---

<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:** [October 29, 2024, 3:10pm UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871/5 "2024-10-29T15:10:59Z")

</div>

> [@YF129701](#):
>
> This has worked reliably

Watch out! Even the assignment to `self.props.items` is asynchronous. You should use `newTreeItems[0].items` instead of referencing `self.prop.items[0].items`.

---

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [October 29, 2024, 3:13pm UTC](https://forum.inductiveautomation.com/t/how-to-reliably-call-a-function-after-refreshbinding/97871/6 "2024-10-29T15:13:16Z")

</div>

That is good to know that the assignments are async... I realized I could just use `newTreeItems` as I was watching you type, waiting to see if I was about to get OWNED with FACTS AND LOGIC.

Thanks for your input!

#### Edit just for completeness:

As Phil noted, I could just use the `newTreeItems` property. However, I did have to change from dot notation to `[""]` to access object properties. So, my script ended up being like

```python
newTreeItems = my.shared.script(p1, p2) # generates tree instances
self.props.items = newTreeItems

items = newTreeItems[0]["items"] # instead of [0].items
...

```
