Barcode navigation errors

Ignition Version 8.0.17
I am trying to use a barcode scanner input in my header to navigate to a particular view with no success.

The data prop change script is this:

	value = currentValue.value[0].value
	value = str(value)
	if len(value) > 0:
		self.session.custom.barcode = value

	self.props.data = 0

Where the following error shows up in the logs.
Error running property change script on BarcodeScannerInput.props.data: Traceback (most recent call last): File “function:valueChanged”, line 1, in valueChanged TypeError: ‘int’ object is unsubscriptable

If I am looking at a label on my screen bound to this barcode session property, it is actually changing correctly from “Enamel Line 1” to “Enamel Line 2” etc… I haven’t tried scanning barcodes without spaces however.

Then to do the navigation I ended up moving that code to the session property change script as follows:

	this = currentValue.value
	#Do label based navigation
	if this.startswith('Enamel'):
	
		#system.perspective.navigate(page = 'enamel/lineview', pageId=context.pageId)
		system.perspective.navigate(view = 'enamel/lineview', params = {'LineNo':1})

This thread title is a little misleading as it appears that there is no navigation issue and in fact the issue is entirely based in your scripting of the event. The error you are encountering is due to currentValue.value being an int, while you’re treating it as an array type (iterable).

# Change this
value = currentValue.value[0].value
# to this
value = currentValue.value

I don’t think that will work. My barcode scanner input component is returning a dataset. If I do what you suggested, I get this [‘Enamel Line 1’]

Sorry, but I’m only going off of the error you provided and the code you provided. Could you provide a screenshot of the Barcode Scanned Event dialog where your code lives so that I can verify the line I suggested you change is indeed line 1?

It is returning the correct value from the barcode label, I don’t understand why an error is being thrown because it seems to work. The other error being thrown on the navigation is this

Error running property change script on session.custom.barcode: Traceback (most recent call last): File “function:valueChanged”, line 11, in valueChanged at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.lambda$operateOnPage$22(PerspectiveScriptingFunctions.java:739) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.operateOnSession(PerspectiveScriptingFunctions.java:795) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.operateOnPage(PerspectiveScriptingFunctions.java:722) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.navigate(PerspectiveScriptingFunctions.java:166) at jdk.internal.reflect.GeneratedMethodAccessor224.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: No perspective page attached to this thread.

and here is where I am trying to do the navigation

Oh, okay, the problem is that there is no Perspective Page thread attached to the change event on the session property, so when that changes the application doesn’t know which page to perform the navigation on.

If you look at the documentation for the navigate function, you’ll see verbiage along the lines of “will use the current page”, but “session” properties are not intrinsically tied to any page. You can still get this to work if you also specify a pageId argument for the navigation call.

My recommendation:
Instead of using a session property for the barcode value, you should set a custom property on the barcode scanner component itself and perform the property change script logic on this new custom property since the component is part of a page.

If for some reason you do need that barcode value available to the entire session then you should still follow the steps I just suggested, in addition to setting the session property.

Note:
If you do perform navigation to a PAGE, code executed after the navigation call could potentially fail as the original page would no longer exist. This is not a problem when performing VIEW navigation. If you do switch to the page navigation you have commented out, you can remove the pageId argument as the navigation will default to the current page (plus the context variable which seems to have been copied form a Barcode Scanned Event no longer exists in this context).

OK that makes sense, so I am tying the barcode event to the header page because I want it to work no matter which main view is currently open. I have more barcode inputs in the main pages to fill in data into the fields.

I am using the mobile perspective app to do this.
Can I lookup the current main view and get the pageID so that way I can call the navigation to swap that one instead of the header?

Do you mean Docked View? Assuming you do, you don't need to look up the pageId because the Docked View is still part of the page and so has access to the required Page thread. One thing to keep in mind is that whether you perform View navigation or Page navigation, only the primary (central) panel will change - NOT the Docked View. Page navigation will change the displayed URL and will allow you to use the browser's back button should you need to go back to a previous page, whereas View navigation will NOT change the URL and clicking the back button could have unintended consequences; neither route will directly affect the Docked View.

So if you have the Docked View set as a shared docked view (such that it is used for "every" page in the project), then your navigation should have no effect on the docked view.

I do mean a shared docked view, yes.

I tried what you suggested on the custom property on that component, like so.
I get view not found message on my device.

The docs specify that when doing page navigation you must specify the URL of the page you want to visit. Page configurations require that the url must begin with a leading slash. If you examine the page config you want to navigate to, copy the url you see there and try again.

I’m willing to bet that you just need a leading slash:

system.perspective.navigate(page='/enamel/lineview')

Note:
I’m not positive about the last logger line you have; it might cause an error or warning as the page thread it is reliant on will probably no longer exist after the navigation occurs. It also might not, depending on timing.

That got it working. Still keep getting error in my logs every time I scan.
line 6, in valueChanged TypeError: ‘int’ object is unsubscriptable

I tried using the param for the page navigation but it doesn’t do that so I made another session prop for the line number itself and I can bind a custom prop on the view to it but now how will I do parameter input to the page from say a menu navigation? Is there a better way to pass in parameters with barcode navigation?

I still suspect that it's the Barcode Scanned Event. Line 6 attempts to access currentValue.value[0] which would throw that error if the value is an int instead of an array. place a logging line in that script to print out the scanned value BEFORE you do anything with it.

logger.info('Value scanned: {0} || type: {1}'.format(currentValue.value, str(type(currentValue.value))))

That got it.

	logger = system.util.getLogger('header barcode scanner')
	#logger.info('Value scanned: {0} || type: {1}'.format(currentValue.value, str(type(currentValue.value))))
	if currentValue.value != 0 and len(currentValue.value)>0:
		value = currentValue.value[0].value
		value = str(value)
		#if len(value) > 0:
		self.session.custom.barcode = value
		self.session.custom.line = value.split(' ')[-1]
		self.props.data = []
1 Like

Any idea where the 0 was coming from?