# Passing tagpath to generic sidebar for display of live values

**URL:** <https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808>\
**Category:** Ignition\
**Created:** [December 18, 2019, 7:19pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808 "2019-12-18T19:19:52Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![llepore](https://avatars.discourse-cdn.com/v4/letter/l/5daacb/32.png) [@llepore](https://forum.inductiveautomation.com/u/llepore)\
**Post date:** [December 18, 2019, 7:19pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/1 "2019-12-18T19:19:52Z")

</div>

Hi all,

Do you have a best practice way to do this? currently the way I’m doing it based on which component on the screen is selected I pass the tag to a client tag, the ‘sidebar’ template reads the tagpath from the client tag and I have some custom methods to read the tags in that tagpath. I have custom properties which have a runScript expression calling the custom method to populate the dataset. Once I have the dataset I use template repeater to display in the sidebar. I don’t think this is the most efficient and there must be a better way, it worked well during development but now the UI is extremely slow and hardly works.

Thanks!

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/2X/0/017a123826db375cc953764fb69484daebdc2651.png)

---

<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:** [December 18, 2019, 8:03pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/2 "2019-12-18T20:03:21Z")

</div>

> [@llepore](#):
>
> now the UI is extremely slow and hardly works.

I'm gonna guess you are calling readStates() from the bolded propertyChange event?

You are browsing tags inside an event. Not only does browsing call out to the gateway, it is notoriously slow. Inside an event, that freezes your UI. Even scripted tag reads (other than client tags) should not be done in event scripts.

Use indirect binding to read your dynamically selected tag, using a string property for the whole tagpath. Do your tag browsing in a background thread (invokeAsynchronous) and pass the results (tagpath) back to the foreground UI with invokeLater.

---

<div class="post-metadata">

**Author:** ![llepore](https://avatars.discourse-cdn.com/v4/letter/l/5daacb/32.png) [@llepore](https://forum.inductiveautomation.com/u/llepore)\
**Post date:** [December 18, 2019, 8:51pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/3 "2019-12-18T20:51:58Z")

</div>

I’m calling readStates() from an internal property which builds the dataset:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/2X/5/5c18a0f370fd5dfb03fd2a76b5311f8a81a6428b.png)

Now I have a dataSet with {key:value} pairings and I display that on the sidebar with template repeater.

Inside the propertyChange I call the script again which catches any property changes if any of the state tags change.

Can you provide an example of the async and invokelater, I was trying to get that to work before but I don’t believe I was implementing properly.

Code: {tags = system.tag.browseTagsSimple(states, “ASC”)  
data =   
for tag in tags:  
if “Spare” not in tag.name:  
data.append([tag.name, system.tag.read(tag.path).value])  
tempDataSet = system.dataset.toDataSet([‘Key’, ‘Value’], data)  
print ‘readStates’  
return tempDataSet}

Thanks.

---

<div class="post-metadata">

**Author:** ![scicco](https://avatars.discourse-cdn.com/v4/letter/s/e0b2c6/32.png) [@scicco](https://forum.inductiveautomation.com/u/scicco)\
**Post date:** [December 18, 2019, 10:09pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/4 "2019-12-18T22:09:58Z")

</div>

Not sure if this is the same as what you’re trying to do but I have a tag browser where users can select up to 5 tags and see them charted in real time on a rolling configurable amount of time. The 5 limit is arbitrary - the chart just needs the same number of dataset properties.

If that’s what you’re after I could post more info.

 ![Capture](https://us1.discourse-cdn.com/inductiveautomation/original/2X/0/0c33dd3801339dde216c33235a0861c5f1b358db.png)

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [December 18, 2019, 10:35pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/5 "2019-12-18T22:35:02Z")

</div>

> [@llepore](#):
>
> {tags = system.tag.browseTagsSimple(states, “ASC”)  
> data =   
> for tag in tags:  
> if “Spare” not in tag.name:  
> data.append([tag.name, system.tag.read(tag.path).value])  
> tempDataSet = system.dataset.toDataSet([‘Key’, ‘Value’], data)  
> print ‘readStates’  
> return tempDataSet}

You really need to put this into preformatted text (using code surrounded by pairs of ```) on the forum to preserve formatting (in particular tabs) and make your code readable:

```auto
tags = system.tag.browseTagsSimple(states, “ASC”)
data = []
for tag in tags:
    if “Spare” not in tag.name:
        data.append([tag.name, system.tag.read(tag.path).value])
tempDataSet = system.dataset.toDataSet([‘Key’, ‘Value’], data)
print ‘readStates’
return tempDataSet

```

---

<div class="post-metadata">

**Author:** ![llepore](https://avatars.discourse-cdn.com/v4/letter/l/5daacb/32.png) [@llepore](https://forum.inductiveautomation.com/u/llepore)\
**Post date:** [December 18, 2019, 10:45pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/6 "2019-12-18T22:45:26Z")

</div>

ok thanks

---

<div class="post-metadata">

**Author:** ![llepore](https://avatars.discourse-cdn.com/v4/letter/l/5daacb/32.png) [@llepore](https://forum.inductiveautomation.com/u/llepore)\
**Post date:** [December 20, 2019, 1:05am UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/7 "2019-12-20T01:05:45Z")

</div>

```auto
def readStates(self, states, refresh=none)
     //invoke later, not exactly sure how to call this
     def browseTags
          tags = system.tag.browseTagsSimple(states, “ASC”)
          data = []
          for tag in tags:
               if “Spare” not in tag.name:
                  data.append([tag.name, system.tag.read(tag.path).value]) tempDataSet = 
              system.dataset.toDataSet([‘Key’, ‘Value’], data)
     system.util.invokeAsynchronous(browseTags)

print ‘readStates’
return tempDataSet
//also unsure about calling async at the end of the function
system.util.invokeAsynchronous(readStates(self, states))

```

Would it make sense to call async on the internal frame opened of the sidebar or something like I have started above?

---

<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:** [December 20, 2019, 1:01pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/8 "2019-12-20T13:01:03Z")

</div>

You have syntax and logix errors. Your def browseTags needs parentheses and a colon. You aren't assigning the returned dataset from toDataSet() to a variable, so it goes in the bitbucket beside your laptop. (It's also indented one too far--it should be run after the loop.) When you have it assigned to a variable, you'll need an invokeLater() to safely assign it to a component.

Also, you can't pass any parameters to the function called in invoke\*. See my helper functions in later.py for alternatives:

> [@Update GUI via Asynchronous thread](http://forum.inductiveautomation.com/t/update-gui-via-asynchronous-thread/9666/3):
>
> Since this sort of thing pops up often, I created a set of wrappers that simplify this stuff, and allows you to directly use functions in your script modules. The wrappers take care of stuffing the arguments you supply into a temporary fuction’s default argument. For your case, try assignLater(). Nick’s example becomes: # In a script module in your project: import shutil def fileTransfer(label): path = system.file.openFile() newPath = "F:\NewFolder" shutil.copy2(path, newPath) sh…

{ If you search this forum for invokeLater or invokeAsynchronous, you'll find many more examples. }

---

<div class="post-metadata">

**Author:** ![llepore](https://avatars.discourse-cdn.com/v4/letter/l/5daacb/32.png) [@llepore](https://forum.inductiveautomation.com/u/llepore)\
**Post date:** [December 20, 2019, 3:50pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/9 "2019-12-20T15:50:25Z")

</div>

> [@pturmel](#):
>
> t

Thanks, so if I can't pass the required tagpath that needs to be browsed into the function then I don't think the invoke\* will work for this case

---

<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:** [December 20, 2019, 3:55pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/10 "2019-12-20T15:55:06Z")

</div>

> [@llepore](#):
>
> so if I can’t pass

Look at the examples for the alternate techniques for passing information into these functions, or just use the functions in later.py that do it for you.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [December 21, 2019, 10:33pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/11 "2019-12-21T22:33:13Z")

</div>

Arguments don’t need to be passed into this function though, do they @pturmel? They’re available to the inside of the function as they exist when the function is created.

E. G.

```auto
states =... 
refresh = none
def readStates():
     #invoke later, not exactly sure how to call this
     def browseTags() :
          tags = system.tag.browseTagsSimple(states, “ASC”)
          data = []
          for tag in tags:
               if “Spare” not in tag.name:
                  data.append([tag.name, system.tag.read(tag.path).value]) tempDataSet = 
              system.dataset.toDataSet([‘Key’, ‘Value’], data)
     system.util.invokeAsynchronous(browseTags)

print ‘readStates’
return tempDataSet
#also unsure about calling async at the end of the function
system.util.invokeAsynchronous(readStates)

```

---

<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:** [December 22, 2019, 2:19pm UTC](https://forum.inductiveautomation.com/t/passing-tagpath-to-generic-sidebar-for-display-of-live-values/30808/12 "2019-12-22T14:19:19Z")

</div>

> [@nminchin](#):
>
> as they exist when the function is created

Yes, in this case. My later.py was modified to take advantage of such _closures_ where applicable. Note that the variables in question must be _named_ in the inner functions to be captured in the outer scope. Indirect access to outer variables doesn't work.
