Iterating through piston arguments via URL


#1

1) Give a description of the problem
I am trying to iterate through the $args key-value pairs passed to a piston by calling its external URL. Essentially I have a variable number of arguments, e.g.

https://externalURL?arg1=val&arg2=val
https://externalURL?arg1=val&arg2=val&arg3=val

Most examples I see put the arguments into a local variable by name (e.g. $args.arg1, arg2, …)

However, I would like to use a loop that iterates through the list of supplied arguments that I gave on the URL as I don’t know in advance how many were supplied. There seems to be no documentation on $args, and some examples I see really don’t do this.

2) What is the expected behaviour?
pseudo code:

for i=0; i<$args.length; ++i
extract the keyname in $args[i] // eg arg1
extract the value in $args[i] // eg val
end

3) What is happening/not happening?
Failing to figure out the length of $args
Tried length($args) and $args.length none seem to give the right amount so i don’t exceed the arrayItem(n, $args) n value for the array

I also see that there are a number of “invisible” arguments passed (e.g. param1, param2, …) that come along with the argument list, so I need to know to stop iterating when I hit these

Also not sure how to extract the key and value for each arg without doing a lot of string manipulation (e.g. to the left of the : is the key, to the right is the value)

THANKS in advance!


#2

I am not sure if what you are trying to do will work. The problem is the way webcore treats lists. If you look at $args[0], I expect you will see null. That is because webcore uses the keyname as the index. Typically, val will be stored in $args.arg1 or $args[arg1]. It won’t understand $args[0]. Here is an example of a piston I have. This is called from another piston with variables supplied as the arguments so you have to use the calling piston variable names to get the data.

02%20AM

A couple suggestions to try:

  1. Use numbers instead of names for your arguments:

https://externalURL?1=val&2=val

Then you can use 1, 2, … for your indices. I have not tried this so not sure if it will be accepted.

  1. Pass your number of arguments as your first argument:

https://externalURL?0=3&1=val&2=val


#3

Appreciate the reply. I think I can get through it in-elegantly with your suggestion. But, just to explore one more thing, is there a way to have an expression evaluated indirectly based on a text variable containing the object name?

So, let’s say we always have parameters msg1, msg2, … n If I iterate i in a loop from 1 through n, is there a way to have webcore evaluate ($args.msg{i}) so the first time through the loop it pulls the object $args.msg1, then $args.msg2, etc.


#4

I wasn’t sure it would be possible but I did a quick test as shown below. Looks like you can do it with a slightly different syntax. You need to create your string index in a separate variable and then it will work using [] syntax. I haven’t tested actually using $args but it should work the same. I’ll leave it up to you to experiment further. Please report back on your results for future reference. thanks,

Log:

11/3/2020, 12:48:59 AM +112ms
+120ms	║[arg1:This is argument 1, arg2:This is argument 2, arg3:This is argument 3]
+143ms	║This is argument 1
+165ms	║This is argument 2
+185ms	║This is argument 3

#5

Try as I might, I could not get that to work with $args

Here’s what I landed on – a generic args processor (a finite number of parameters) into key-value pairs.

In my case, I executed the URL: https://…?arg1=woo&arg2=hoo

The log resulted:
image

You can see that WC adds 3 arguments, so you have to process those out in your code, but at least this gives you programmatic access to all supplied key-value pairs on the URL


#6

I just did a little test and it works fine:

11/3/2020, 11:46:21 AM +165ms
+1ms	╔Received event [Las Vegas].execute = 72.■■■.123 with a delay of 10363ms
+145ms	║[arg1:This is argument 1, arg2:This is argument 2, arg3:This is argument 3]
+170ms	║This is argument 1
+192ms	║This is argument 2
+213ms	║This is argument 3
+225ms	║arguments are: [arg1:woo, arg2:hoo, param1:execute, param2::92789727128f5dbbeb6637bfb15a20ab:, remoteAddr:72.■■■.123]
+248ms	║woo
+269ms	║hoo
+292ms	║null
+302ms	╚Event processed successfully (302ms)

You have to use an expression for $args since it won’t recognize it as a list and you can’t have any spaces in the brackets. Take a look at my updated piston:

As I look at the result and how it works, you could keep going with arg1, arg2,…,argN and just stop when argi=null (bool(argi)=‘false’) as seen above. I only provided 2 arguments so the 3rd was null. No need to pass the numb er of arguments.


#7

You’re right, I must have fat-fingered a test… it works great:

and the log output:
image

This code is better if you’re expecting a set of arg[1…n] parameters (i.e., having a fixed named parameter, in this case arg#), vs. the prior code which just lets you iterate through all the arguments whatever they are named

You’ll note that I did have to do some odd calisthenics to detect the end of the args, as just comparing value to ‘null’ didn’t seem to work.

Great job @guxdude Guy! Thank you! You saved my sense of coding sanity :slight_smile:


#8

That is why I mentioned the bool function. If you do bool(value) it will only be true if the string is non-null. More foolproof way of finding null values. For some reason, comparing to null never seems to work.

Anyway, glad this is working for you. It is a handy tool I will keep for potential future use.


#9

Hi,
I just try to do exactly what you said but its not working! Can you gives more details on what you are doing? For now I have my url with arg inside but I cannot get those with index value and if I only use $args it wont gives me anything, I must go with the name ($args.value). Thanks!