Passing View Custom Parameters to Another View as Parameters

I am still learning so be gentle.

I have database data on a view, lets call it view 1, that I am trying to pass to another view, call it view 2. The data is defined as custom data associated with a drop down selection object. I should note, this data is database data..so datasets of various sizes. There is a button on view one that when enabled and pressed, sets database data and opens a new view while passing the dataset data to parameters defined on view 2.

I have validated data is in my datasets.
I have validated my query is setting the appropriate data on button press.
I have validated my navigation sends me to the correct view.
What I cannot get to work is passing the view custom parameter dataset data to the new view as parameters. My testing method has been to essentially pull out the data in a column to confirm the data is there..but it never is :frowning:

Any help would be greatly appreciated, screen snips of pertinent stuff below.

View 1 Custom Parameters

View 1 Button Script

def runAction(self, event):
	# Gather data for database update
	recipe_id = self.getSibling("Recipe Selection Dropdown").props.value
	# Username in FORCED Uppercase for error proofing
	edits_en_by = self.session.props.auth.user.userName.upper()
	# Datetime data
	edits_en_time = system.date.now()
	
	# Package Parameters
	Parameters = {"recipe_id":recipe_id, "edits_en_by":edits_en_by, "edits_en_time":edits_en_time}
	# Run query
	system.db.runNamedQuery("SetEditsEnable", Parameters)
	
	# Open Recipe Edit view
	# Define view parameters
	RecipeHeaderData = self.getSibling("Recipe Selection Dropdown").custom.SelectedConfigData
	RecipeRoomData = self.getSibling("Recipe Selection Dropdown").custom.SelectedRoomData
	RecipeStepData = self.getSibling("Recipe Selection Dropdown").custom.SelectedStepData
	# Define view path
	view_path = "/Recipe/Edit"
	# Package view parameters
	ViewParameters = {"RecipeHeaderData":RecipeHeaderData, "RecipeRoomData":RecipeRoomData, "RecipeStepData":RecipeStepData}
	# Open view
	system.perspective.navigate(view_path, ViewParameters)

View 2 Parameters

View 2 Validate Data Transfer Expression
{view.params.RecipeHeaderData}[0, "recipe_id"]

Thank you in advance for any help!

On second thought...it would probably be waaayyy easier to just pass the index number and query the data again on view 2. However, given I have already gone down this path I am still hoping someone can tell me what I am doing wrong.

Please post the code as formatted text rather than a picture so that folks can copy / test / edit it. Post a screengrab as well if context might be important. (You have already.) See Wiki - how to post code on this forum.

Code snips updated, apologies!

I don't see anything obviously wrong. But, are you testing in a real session? (Navigation doesn't work in designer preview.)

I should also note, I am doing something similar on view 1 in terms of passing the dataset data around. I have an embedded object that is passed the large dataset and configured such that the user can index through it.

So the view custom dataset data is getting passed into multiple embedded views but it doesnt seem to want to get passed off the view.

Yes, I am testing in a real session.

Consider copying that view temporarily to a new name, then editing to replace the entire content with a full-size text area component (grow:1). Set it's props.text to this expression:

runScript("system.util.jsonEncode", 0, {view.params}, 2)

That will show you in json form what your view is receiving for parameters.

I did this, the label text evaluates to null.

Use system.util.jsonEncode() in view1 to stringify your ViewParameters and log that.

I think this is what you wanted me to do..I made this change to the button script on view 1:

RecipeHeaderData = system.util.jsonEncode(self.getSibling("Recipe Selection Dropdown").custom.SelectedConfigData)
	RecipeRoomData = system.util.jsonEncode(self.getSibling("Recipe Selection Dropdown").custom.SelectedRoomData)
	RecipeStepData = system.util.jsonEncode(self.getSibling("Recipe Selection Dropdown").custom.SelectedStepData)

That still yields a null evaluation on the test screen.

No, pass the original ViewParameters dictionary to system.util.jsonEncode() to stringify the parameters dictionary to make it logger-friendly. Use a logger from system.util.getLogger() to push that information to the gateway log.

Okay, so I keep getting this error in the gateway logger. I have not yet been able to get it to log the data. I am in the middle of reading the manual in regards to the logger function but I wanted to share this real quick.

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 23, in runAction RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)

at org.python.core.Py.RuntimeError(Py.java:155)

at org.python.core.Py.JavaError(Py.java:538)

at org.python.core.Py.JavaError(Py.java:536)

at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:192)

at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:553)

at org.python.core.PyObject.__call__(PyObject.java:461)

at org.python.core.PyObject.__call__(PyObject.java:465)

at org.python.pycode._pyx901.runAction$1(:27)

at org.python.pycode._pyx901.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:173)

at org.python.core.PyBaseCode.call(PyBaseCode.java:306)

at org.python.core.PyFunction.function___call__(PyFunction.java:474)

at org.python.core.PyFunction.__call__(PyFunction.java:469)

at org.python.core.PyFunction.__call__(PyFunction.java:464)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:847)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:829)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:868)

at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1010)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:950)

at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:161)

at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:98)

at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:80)

at com.inductiveautomation.perspective.gateway.action.ActionDecorator.runAction(ActionDecorator.java:18)

at com.inductiveautomation.perspective.gateway.action.SecuredAction.runAction(SecuredAction.java:44)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:263)

at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:252)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:221)

at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)

at java.base/java.lang.Thread.run(Unknown Source)

Caused by: org.python.core.PyException: RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)

... 35 common frames omitted

This is my current script for testing. I have commented everything out so it is just packaging the data sending it to the logger but I keep getting that overflow error.

def runAction(self, event):
	# Gather data for database update
	# recipe_id = self.getSibling("Recipe Selection Dropdown").props.value
	# Username in FORCED Uppercase for error proofing
	# edits_en_by = self.session.props.auth.user.userName.upper()
	# Datetime data
	# edits_en_time = system.date.now()
	
	# Package Parameters
	# Parameters = {"recipe_id":recipe_id, "edits_en_by":edits_en_by, "edits_en_time":edits_en_time}
	# Run query
	# system.db.runNamedQuery("SetEditsEnable", Parameters)
	
	# Open Recipe Edit view
	# Define view parameters
	RecipeHeaderData = self.getSibling("Recipe Selection Dropdown").custom.SelectedConfigData
	RecipeRoomData = self.getSibling("Recipe Selection Dropdown").custom.SelectedRoomData
	RecipeStepData = self.getSibling("Recipe Selection Dropdown").custom.SelectedStepData
	# Define view path
	# view_path = "/Recipe/Edit"
	# Package view parameters
	ViewParameters = {"RecipeHeaderData":RecipeHeaderData, "RecipeRoomData":RecipeRoomData, "RecipeStepData":RecipeStepData}
	system.util.jsonEncode(ViewParameters)
	logger = system.util.getLogger("myParamsLogger")
	logger.info(ViewParameters)
	# Open view
	# system.perspective.navigate(view_path, ViewParameters)

I think I see my mistake..

Edit: I did not not see my mistake. Well I saw mistakes, but I still cant get the damn thing to log the data to the gateway.

# Open Recipe Edit view
	# Define view parameters
	RecipeHeaderData = self.getSibling("Recipe Selection Dropdown").custom.SelectedConfigData
	RecipeRoomData = self.getSibling("Recipe Selection Dropdown").custom.SelectedRoomData
	RecipeStepData = self.getSibling("Recipe Selection Dropdown").custom.SelectedStepData
	# Define view path
	# view_path = "/Recipe/Edit"
	# Package view parameters
	ViewParameters = {"RecipeHeaderData":RecipeHeaderData, "RecipeRoomData":RecipeRoomData, "RecipeStepData":RecipeStepData}
	testString = system.util.jsonEncode(ViewParameters)
	logger = system.util.getLogger("myParamsLogger")
	logger.infof(testString)

Error running action 'component.onActionPerformed' on Page/Recipe/Recipe Database@C/root/View Container/Top Container/Edit Recipe Button: Traceback (most recent call last): File "<function:runAction>", line 23, in runAction RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)

Line 23 is the one starting with testString

Walking away for a minute to scream.

1 Like

Uh oh. That means your selection data has an deep reference to an outer level. Which makes for infinite recursion when jsonification is attempted. Try constructing your ViewParameters with those elements one at a time, jsonifying at each step, to see which of the three has bogus content.

My gut is that your selection datasets have references to objects instead of clean primitive valued content. You should show how you are constructing them.

Starting from the top, the drop down selection object is the object that has the custom property tags. The options for that object is a query binding executing every 5 seconds. The intent here is to just populate the drop down list with possible selections.

Drop Down Object Options Expression Binding

I have custom parameters (not sure if that is the right term) associated with the same drop down selection object. Based on the current value, I run a query expression binding to pull the appropriate data from all the various tables.

Drop Down Object Custom Parameter Typical Expression

From here I reference these custom parameters all across the view. I hit them directly and I pass them into embedded views. They are not getting passed around beyond this and my attempt to get them into another view.

The thought process is..I have already queried the data, I should be able to pass it to another view to edit and then either commit or discard changes there. However, I am very much getting to the point where I am just going to pass the current value of the drop down selection object and re-query the data there.

Im not sure if that answers your question completely. Again, I am still learning.

Figured it out..

It is the damn system.perspective.navigate() instruction.

Minus some "" vs '' syntax errors, this does NOT work..any combination of path I can think of results in the navigation to a page without a defined view.

def runAction(self, event):
	# Gather data for database update
	recipe_id = self.getSibling("Recipe Selection Dropdown").props.value
	# Username in FORCED Uppercase for error proofing
	edits_en_by = self.session.props.auth.user.userName.upper()
	# Datetime data
	edits_en_time = system.date.now()
	
	# Package Parameters
	Parameters = {"recipe_id":recipe_id, "edits_en_by":edits_en_by, "edits_en_time":edits_en_time}
	# Run query
	system.db.runNamedQuery("SetEditsEnable", Parameters)
	
	# Open Recipe Edit view
	# Define view parameters
	RecipeHeaderData = self.getSibling("Recipe Selection Dropdown").custom.SelectedConfigData
	RecipeRoomData = self.getSibling("Recipe Selection Dropdown").custom.SelectedRoomData
	RecipeStepData = self.getSibling("Recipe Selection Dropdown").custom.SelectedStepData
	# Define view path
	view = 'Page/Recipe/Recipe Edit Test'
	# Package view parameters
	params = {'recipe_id':recipe_id, 'RecipeHeaderData':RecipeHeaderData, 'RecipeRoomData':RecipeRoomData, 'RecipeStepData':RecipeStepData}
	# Open view
	system.perspective.navigate(view, params)

However, this works all day long

def runAction(self, event):
	# Gather data for database update
	recipe_id = self.getSibling("Recipe Selection Dropdown").props.value
	# Username in FORCED Uppercase for error proofing
	edits_en_by = self.session.props.auth.user.userName.upper()
	# Datetime data
	edits_en_time = system.date.now()
	
	# Package Parameters
	Parameters = {"recipe_id":recipe_id, "edits_en_by":edits_en_by, "edits_en_time":edits_en_time}
	# Run query
	system.db.runNamedQuery("SetEditsEnable", Parameters)
	
	# Open Recipe Edit view
	# Define view parameters
	RecipeHeaderData = self.getSibling("Recipe Selection Dropdown").custom.SelectedConfigData
	RecipeRoomData = self.getSibling("Recipe Selection Dropdown").custom.SelectedRoomData
	RecipeStepData = self.getSibling("Recipe Selection Dropdown").custom.SelectedStepData
	# Define view path
	# view = 'Page/Recipe/Recipe Edit Test'
	# Package view parameters
	# params = {'recipe_id':recipe_id, 'RecipeHeaderData':RecipeHeaderData, 'RecipeRoomData':RecipeRoomData, 'RecipeStepData':RecipeStepData}
	# Open view
	system.perspective.navigate(view = 'Page/Recipe/Recipe Edit Test', params = {'recipe_id':recipe_id, 'RecipeHeaderData':RecipeHeaderData, 'RecipeRoomData':RecipeRoomData, 'RecipeStepData':RecipeStepData})

Check the system.perspective.navigate documentation.

Without using the keywords for the parameters the function will default to navigating using the path (as defined in the Perspective Page Configuration). The params parameter is only to be used with the view option for navigation (which is why it works in your second script).

If you are navigating with the path you can use URL Parameters.