# Perspective JSON as parameter for script

**URL:** <https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [October 26, 2021, 3:15pm UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353 "2021-10-26T15:15:18Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![mori.luca](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mori.luca/32/13424_2.png) [@mori.luca](https://forum.inductiveautomation.com/u/mori.luca)\
**Post date:** [October 26, 2021, 3:15pm UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/1 "2021-10-26T15:15:18Z")

</div>

Hello, I’m using a JSON from a perspective view to build a sort of wizard.

I made some input box binding to some properties of the JSON and everything is ok, then I have two buttons with some scripts and I’d like to understand what’s going on.

Pressing the first button I read the JSON and I pass it as an argument to a script function like this :

```auto
 obj = self.view.getChild("root").custom.porta #<-- json from perspective
 func1.Go(obj)
 func2.Go(obj)

```

func1 : modify state of JSON  
func2 : print out JSON obj

I notice that func2 seams to work on a not updated JSON, and if I print the state I can clearly see that the attributes are not being modified from func1.

However, if I check the JSON state from the GUI I can see that the attributes are changed.

If i repeat the process, i can see on the output that the JSON is updated from the last call, so i end up always with one iteration of delay.

Button 1 :

```auto
 obj = self.view.getChild("root").custom.porta #<-- json from perspective
 func1.Go(obj)
 sleep(10)
 func2.Go(obj)

```

Button 2 :

```auto
 obj = self.view.getChild("root").custom.porta #<-- json from perspective
 system.perspective.print(obj)

```

Clicking the first button and then the second one, I can see JSON printed out is correctly being modified from func1, however after 10 seconds I got the printed text from func2 JSON printed is not updated.

I noticed some strange behavior when working with arrays too.

Am I missing something or am I not supposed to work in this way?

* * *

* * *
Adding a note : 

A way to reproduce is to create a JSON like this one :  
 ![Schermata 2021-10-26 alle 18.07.15](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/7/b7d96aa2ec3263e183712dae5cb84de749fe99d1.png)

First button Script :

```auto
obj = self.view.custom.test
	
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1

```

index get incremented by 1.

Second Button :

```auto
self.view.custom.test.val_1.index += 1
self.view.custom.test.val_1.index += 1
self.view.custom.test.val_1.index += 1

```

It work as expected.

Thank you

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 26, 2021, 3:26pm UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/2 "2021-10-26T15:26:25Z")

</div>

I’m guessing you’re updating the view param, not the `obj` you’re passing to your functions.  
try

```python
obj = self.view.getChild("root").custom.porta #<-- json from perspective
func1.Go(obj)
obj = self.view.getChild("root").custom.porta #<-- json from perspective 
func2.Go(obj)

```

and see if it works as intended.

---

<div class="post-metadata">

**Author:** ![mori.luca](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mori.luca/32/13424_2.png) [@mori.luca](https://forum.inductiveautomation.com/u/mori.luca)\
**Post date:** [October 26, 2021, 3:28pm UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/3 "2021-10-26T15:28:00Z")

</div>

Hi,  
thank you but this was one of the first test i did, Is two days I’m trying to understand what’s going on,  
i did a lots of test 🙂

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [October 27, 2021, 7:23am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/5 "2021-10-27T07:23:06Z")

</div>

can you show func1 and 2?  
objects and arrays work with references, so depending what you do with them, they might (not) update the reference.

---

<div class="post-metadata">

**Author:** ![mori.luca](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mori.luca/32/13424_2.png) [@mori.luca](https://forum.inductiveautomation.com/u/mori.luca)\
**Post date:** [October 27, 2021, 7:46am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/6 "2021-10-27T07:46:55Z")

</div>

I don't really have func1 and func2

> objects and arrays work with references

I expected them as work like them, but you can see there is something going on on this step

```auto
obj = self.view.custom.test
	
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1
obj['val_1']['index'] +=1

```

and i think is the same thing that happen when i pass the object to different functions

---

<div class="post-metadata">

**Author:** ![nideyijuyidong](https://avatars.discourse-cdn.com/v4/letter/n/7cd45c/32.png) [@nideyijuyidong](https://forum.inductiveautomation.com/u/nideyijuyidong)\
**Post date:** [October 27, 2021, 8:00am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/7 "2021-10-27T08:00:58Z")

</div>

I've had the same problem.I use this, to get individual objects.

> import deepcopy from copy

.

---

<div class="post-metadata">

**Author:** ![mori.luca](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mori.luca/32/13424_2.png) [@mori.luca](https://forum.inductiveautomation.com/u/mori.luca)\
**Post date:** [October 27, 2021, 8:03am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/8 "2021-10-27T08:03:02Z")

</div>

Thank you, I will try this solution.

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [October 27, 2021, 8:42am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/9 "2021-10-27T08:42:52Z")

</div>

deepcopy doesnt really work for me it seems. giving some type errors “com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ObjectWrapper()”

however this works:

```auto
	obj = self.view.custom.test
	index=obj['val_1']['index']
	index +=1
	index +=1
	index +=1
	index +=1
	index +=1
	obj['val_1']['index'] = index

```

---

<div class="post-metadata">

**Author:** ![nideyijuyidong](https://avatars.discourse-cdn.com/v4/letter/n/7cd45c/32.png) [@nideyijuyidong](https://forum.inductiveautomation.com/u/nideyijuyidong)\
**Post date:** [October 27, 2021, 8:54am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/10 "2021-10-27T08:54:43Z")

</div>

Here is no error with me.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/a/4a625e5326085a6f8aef5af8c7d7c717c19c1119.png)

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [October 27, 2021, 9:02am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/11 "2021-10-27T09:02:10Z")

</div>

for text it works, but when there are objects in it

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [October 27, 2021, 9:05am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/12 "2021-10-27T09:05:50Z")

</div>

> [@mori.luca](#):
>
> JSON from a perspective

Also i would like to note that you are not using json. You are using objects which just look like json.  
Json is just a structure^^

---

<div class="post-metadata">

**Author:** ![nideyijuyidong](https://avatars.discourse-cdn.com/v4/letter/n/7cd45c/32.png) [@nideyijuyidong](https://forum.inductiveautomation.com/u/nideyijuyidong)\
**Post date:** [October 27, 2021, 9:07am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/13 "2021-10-27T09:07:04Z")

</div>

I tried list, tuple, and dictionary, maybe it doesn’t work for some object.

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [October 27, 2021, 9:14am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/14 "2021-10-27T09:14:07Z")

</div>

most of the things im trying doesnt work 😛 maybe just have a thing for trying the impossible xd i always find the edge cases xd

---

<div class="post-metadata">

**Author:** ![mori.luca](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mori.luca/32/13424_2.png) [@mori.luca](https://forum.inductiveautomation.com/u/mori.luca)\
**Post date:** [October 27, 2021, 10:26am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/15 "2021-10-27T10:26:31Z")

</div>

Thank you for the information,  
is that a json from perspective being casted in a python dict? or is not json even at the beginning?

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [October 27, 2021, 10:56am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/16 "2021-10-27T10:56:10Z")

</div>

There is definitly some json involved. The views get saved as json. But there first is a whole bunch of java in between.

---

<div class="post-metadata">

**Author:** ![mori.luca](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mori.luca/32/13424_2.png) [@mori.luca](https://forum.inductiveautomation.com/u/mori.luca)\
**Post date:** [October 27, 2021, 7:03pm UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/17 "2021-10-27T19:03:46Z")

</div>

I found a very ugly solution but it’s working so I’m going with this one for the moment.

I start the script by encoding/decoding the JSON(?) from perspective session, this way I know I’m working with a decoupled pyDictionary and passing this object to functions work as expected.

Then at the bottom of the script i assign the pyDictionary back to the perspective object.

```auto
porta = system.util.jsonEncode( self.view.getChild("root").custom.porta )
porta = system.util.jsonDecode( porta )

	
Models.Wizard.ComposeItemsCoordinateFromRules(porta)
Models.Wizard.CalcoloPuntiSaldaturaManiglia(porta)
Models.Wizard.ComposeOmega(porta)
Models.Wizard.CalcoloPuntiSaldaturaDeviatori(porta)
Models.Wizard.CalcoloPuntiSaldaturaCerniere(porta)
Models.Wizard.CalcoloPuntiSaldaturaOmega(porta)

self.view.getChild("root").custom.porta = porta

```

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [November 2, 2021, 9:03am UTC](https://forum.inductiveautomation.com/t/perspective-json-as-parameter-for-script/52353/18 "2021-11-02T09:03:17Z")

</div>

This code creates a deepcopy (the correct way):

> [@Function to convert json string or python dict into ObjectWrapper](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/16):
>
> Forcing each to the expected type while traversing makes a deep copy: def sanitize\_tree(element): if hasattr(element, '\_\_iter\_\_'): if hasattr(element, 'keys'): return dict((k, sanitize\_tree(element[k])) for k in element.keys()) else: return list(sanitize\_tree(x) for x in element) return element EDIT: Got rid of the unnecessary zip() and used only one keys() iterator instead of two.

If you put it in a project script it should be easyenough to use

```auto
	def sanitize_tree(element):
		    if hasattr(element, ' __iter__'):
		        if hasattr(element, 'keys'):
		            return dict((k, sanitize_tree(element[k])) for k in element.keys())
		        else:
		            return list(sanitize_tree(x) for x in element)
		    return element
		    
	obj = sanitize_tree(self.view.custom.test)
			
	obj['val_1']['index'] +=1
	obj['val_1']['index'] +=1
	obj['val_1']['index'] +=1
	obj['val_1']['index'] +=1
	obj['val_1']['index'] +=1
	
	self.view.custom.test = obj

```
