Dealing with web_request->param in Lasso 9
Published on
Lasso 9's new "web_request->param" behaves quite differently to action_param found in previous versions of Lasso. It's lower-level, and a little more verbose, but significantly faster - which makes it an obvious tool to master.
Simple usage:
web_request->param('myparam')
… returns the GET or POST param "myparam". However, it returns it as a "bytes" type, which for many situations is not particularly useful. Therefore best usage for retrieving simple params is:
web_request->param('myparam')->asString
For the backwards looking people out there, that's equivalent to [string(web_request->param('myparam')]
Dealing with checkbox and multi-select inputs
This is where action_param made life pretty easy for us. It just handled it. In the "old" way we could just hit:
local('mylocal' = action_param('somecheckboxes')->split('\r'));
And this would give us an array of values corresponding to the choices the user made in the source form. Unfortunately because we're dealing with a fast, low-level method we're not afforded the luxury here, such is the nature of compromise and speed!
local(mylocal = array)
with n in web_request->params
where #n->first >> 'somecheckboxes'
do => { #mylocal->insert(#n->second->asString) }
Of course at this point you can also implicitly type your data so your array elements are the correct type, something you can't do with action_param split!
Checking to see if a URL contains a parameter
Honestly, while it was possible with action_param there were"issues" at times. web_request->params to the rescue… simply and in one line returning boolean true/false:
http://www.example.com/mypage?myaction
web_request->params->asStaticArray >> 'myaction' ? 'User asked for this!'
Note: the above GET param has no associated value. It's really easy to test if an action_param exists if it has a value, but different if you want to test if it existed without a value. The results can be frustrating especially if you're dealing with a variety of input types.
Pros and Cons
So about now you're asking… if action_param dealt with my params so cleanly, why not stick with it in lasso 9?
Well, here's a non-exhaustive list of the pros and cons for using web_request->params instead:
web_request->params
Pros:
- Faster than action_params (by a large margin)
- Works anywhere in the page, objects, and includes.
- Easier to confirm if a valueless param exists
Cons:
- A little more verbose
- Need to specifically type your return (default is bytes type)
- Requires a little more special handling of checkbox and other multiple return values
action_params
Pros:
- Simple, no fuss
- Handles the abstraction of gathering together multiple value returns like checkboxes
Cons:
- Slow. Dreadfully slow.
- action_params are only accessible in the local scope. Try accessing your form submission inside an inline. Go on, I dare you.
Now, I realize there exists a third party set of "tags" called "client_params". I've used them extensively myself - in the past. They provided a great way to allow use of URL and form submitted action_params inside an inline, but it's an abstraction hack on top of an abstraction, made worse by the fact that it's being reconstructed every time, it's not a persistent object. What a recipe for slowness.
Why would you do that when you have web_request->param?
Demonstrating speed difference action_param vs web_request->param
It's been asked for me to provide proof that web_request->param is indeed faster, and by how much.
So here it is. Note the times are in microseconds:
local(start = micros)
loop(10000) => { local(x = action_param('x')) }
'action_param time = '+((micros - #start) / 10000)
'<br>'
local(start = micros)
loop(10000) => { local(x = web_request->param('x')->asString) }
'web_request->param time = '+((micros - #start) / 10000)
## results when called with ?x={anything}:
action_param time = 16
web_request->param time = 8