Perspective URL Dictionary Parameter

Well, I have ticket 111942 “in progress” (from January) with a comment from Adam that canny.io’s new non-third-party-cookie authentication support was being implemented…

Have you tried myPage/:paramOne/:paramTwo?

That works for multiple parameters, but I am looking for a Dictionary parameter

i.e. I want to reach params.TEST.Val1 and params.TEST.Val2

image

Oh. Short answer: no, because the url is just a String. You could string-ify your object for passing through the url, and then expect a string for the param, with a separate custom object which converts it into an object through a binding transform. OR you could have basic value params, and then bind a custom object’s internal values to the view params.

This is what I did as a workaround for now, and I have a script that converts the /Val1=1&Val2=3 format into a dictionary on a custom property.

It just didnt feel like the most scalable way for the future, especially considering you can have Object parameters, it would be nice to be able to utilize those through the URL in some format as well (same with list, but in the meanwhile you could probably do that with /1,2,3,4 parsing into [1,2,3,4])

For prosperities sake though, here is the Ideas post for anyone that runs into this same question
https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/ability-to-pass-dictionary-parameters-to-a-url

Anything passed through the URL can ONLY be a string. If you absolutely MUST pass something like a dictionary, you’re better off using a Session Property and binding the relevant View values to that.

Perspective’s parameter model is built only on the URL path, where parts of the path are substitutions. Is there any possibility of exposing the page’s actual query parameters from the underlying request object? Yeah, I know it is probably complicated by WebSockets, but…

(Haven’t dug under the hood to figure it out myself–too freaking busy.)

Cody’s answer is correct - because pages are defined by their URL, and URLs are just strings, at some point, it’s got to be a string. Even if we were to support some sort of ?param=val style parameter passing, all this would do is open up a page to accepting variable numbers of params, not actual dictionary objects, because again, it’s just a string.

Also, the URLs are mostly a fiction because Perspective is a single-page-app. Beyond the initial http request, there are no more requests from there on out - as you navigate, we just manipulate the URL for you so it looks like you’re navigating in the traditional sense. But the intent of the model is that as you navigate around your pages, the URL is bookmarkable - if you were to land on that URL, it would bring you back to the same place in the app.

You could avoid this by simply eschewing the mounted page system entirely, and just manipulate mounted views & their parameters directly. The downside is that you’d lose the bookmark-ability of navigation and to a user, the app would appear to be all one un-changing URL.

1 Like

I appreciate the clarifications!

I ended up going the route of encoding the URLs in a way that i can decode back into a dictionary for this use case.

For anyone that wants the scripts here they are

# This takes a dictionary of parameters and converts it into a URL parameter string
def dictionaryToURLParameter(params):
	import urllib
	paramList = []
	for key, value in params.items():
		 try: key = urllib.quote(key)
		 except: key = key
		 try: value = urllib.quote(value)
		 except: value = value
		 paramList.append("%s=%s" % (key, value))
	
    # Replace any slashes with pipes so that the perspective URL parser doesnt fail to understand the text
	return "&".join(paramList).replace('/', '|')

# This takes a URL parameter string and converts it into a dictionary of parameters
def URLStringToDictionary(paramString):
	import urllib
    # Replace any pipes with slashes so that the perspective URL parser doesnt fail to understand the text
	paramString = urllib.unquote(paramString.replace('|', '/'))
	params = {}
	for pair in paramString.split('&'):
		pair = pair.split('=')
		params[pair[0]] = pair[1]
	return params
1 Like

I need to get the parameters with the format ‘?code=xxx&scope=yyy’.

I’m trying to use Google OAuth for the Google Drive API and the redirect_uri passes the parameters according to the format above.

When I tried myPage/:param, Ignition was unable to get the parameters due to the ‘?’ Character.

How can I get the ‘code’ and ‘scope’ parameters?

Are you able to preface the Google parameter with a / instead of a ?, if so then you could take the string and extract it into a dictionary

Perspective doesn’t know to count the ? as a delimiter in the URL

No. The Google OAuth API automatically sends with ?

In the entry field where it asks for a callback URL, could you enter it with the default / at the end like so:
ignition.com/data/client/perspective/MyProject/

that way it ends up as ignition.com/data/client/perspective/MyProject/?code=xxx&scope=yyy

1 Like

I tried that. But the ignition fails to get the parameters if there is a ?

I binded a label’s text property with :/code to test it

image

image

As a workaround, I created a PHP page that receives these query parameters and returns to ignition as route parameters.

But I can’t believe this is the best approach

A few notes,

  1. Defining the url parameter should have the colon after the slash like /page/:code
  2. You shouldn’t have to bind the label text to anything similar to /:code because that url parameter translates to view.params.code which is where you should be binding it
  3. It’s weird to see your label acting the way it is, because I use question marks in my parameters and it doesn’t care, let me know if anything above fixes it

Sorry, I typed wrong.

I did as you described in 1 and 2

So, I did more testing, and realized that how I was using a question mark was with its escape value %3F and not the actual ? and so the URL isnt able to detect anything after the ?.

What i think is happening here is that the web server is trying to count anything after the ? as a url parameter in a different way than Perspective is setup to take, and so its ignoring anything after it. I created a support ticket about it, because it kind of feels like a bug, but it also could be an unfortunate limitation of the way Perspective takes its URL parameters vs the way traditional web pages take parameters.

I would be curious to see @cmallonee knows anything about this, and if there is some special escape character you could append at the end of your callback url that would tell perspective to ignore the following character. Similar to putting a \ in a string to treat the following character as its string value rather than its functional value.

1 Like

A bit of an update as I learned some more

The reason that your parameter is failing, and you cant ignore the ? is because the browser thinks that you are trying to provide a query parameter to the web page. You can learn about query parameters vs path parameters here.

Currently Perspective does not support the use of query parameters, however @Carl.Gould did say in the ICC discord the other day that this is something that development is looking into.

Without knowing if its possible to tell ignitions webserver to “ignore” query parameters, I would say that your current solution with the redirect page is probably the way you have to go.

I’m guessing passing parameters with ? is still not supported yet?