Retrieving params of fields with multiple values
Hi guys, I may be missing something here, so I wanted to run this by you: When a form is submitted that has multiple fields with the same name (such as several checkboxes), the values of that field are all returned in an array ref. However, if the same form is submitted, but only one value is returned (eg. only one checkbox has been ticked) then a scalar is returned. If no checkboxes are ticked, then undef is returned. This makes it difficult to process a form with several checkboxes, as the return value from param('checkbox') can be an array ref, scalar or undef, depending how many checkboxes are ticked. At the moment, I'm testing for each of those 3 conditions. Is there a better way? It would be useful if param() could be called in array context, in which case it would return 0, 1 or several items, depending on which ones were checked. Thanks, Andy
You can coerce everything into an arrayref like this (requires 5.10+): my $foo = param 'foo'; $foo = [ $foo // () ] if ref $foo ne 'ARRAY'; for (@$foo) { ... } $foo is now an arrayref with 0, 1, or more elements. You're still checking for undef and arrayref, so this is just a convenient shortcut. On Thu, Aug 21, 2014 at 3:55 AM, Andrew Beverley <andy@andybev.com> wrote:
Hi guys,
I may be missing something here, so I wanted to run this by you:
When a form is submitted that has multiple fields with the same name (such as several checkboxes), the values of that field are all returned in an array ref.
However, if the same form is submitted, but only one value is returned (eg. only one checkbox has been ticked) then a scalar is returned. If no checkboxes are ticked, then undef is returned.
This makes it difficult to process a form with several checkboxes, as the return value from param('checkbox') can be an array ref, scalar or undef, depending how many checkboxes are ticked.
At the moment, I'm testing for each of those 3 conditions. Is there a better way?
It would be useful if param() could be called in array context, in which case it would return 0, 1 or several items, depending on which ones were checked.
Thanks,
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
Similar result as Maxwell suggested, but here is what I do: my $foo = params->{'foo'}; if(defined $foo) { $foo = [ $foo ] unless ref $foo; } On Thu, Aug 21, 2014 at 2:30 PM, Maxwell Carey <mcarey@ucar.edu> wrote:
You can coerce everything into an arrayref like this (requires 5.10+):
my $foo = param 'foo'; $foo = [ $foo // () ] if ref $foo ne 'ARRAY'; for (@$foo) { ... }
$foo is now an arrayref with 0, 1, or more elements. You're still checking for undef and arrayref, so this is just a convenient shortcut.
On Thu, Aug 21, 2014 at 3:55 AM, Andrew Beverley <andy@andybev.com> wrote:
Hi guys,
I may be missing something here, so I wanted to run this by you:
When a form is submitted that has multiple fields with the same name (such as several checkboxes), the values of that field are all returned in an array ref.
However, if the same form is submitted, but only one value is returned (eg. only one checkbox has been ticked) then a scalar is returned. If no checkboxes are ticked, then undef is returned.
This makes it difficult to process a form with several checkboxes, as the return value from param('checkbox') can be an array ref, scalar or undef, depending how many checkboxes are ticked.
At the moment, I'm testing for each of those 3 conditions. Is there a better way?
It would be useful if param() could be called in array context, in which case it would return 0, 1 or several items, depending on which ones were checked.
Thanks,
Andy
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
On Thu, 2014-08-21 at 12:30 -0600, Maxwell Carey wrote:
You can coerce everything into an arrayref like this (requires 5.10+):
my $foo = param 'foo'; $foo = [ $foo // () ] if ref $foo ne 'ARRAY';
for (@$foo) { ... }
Great, thanks for that (and thanks James) - certainly better than what I was doing. However, I still think it would be a neat little feature to be able to write: my @foo = param 'foo' (a bit like you can with uploads). Would a patch for such a feature be accepted? Thanks, Andy
On 14-08-22 06:25 AM, Andrew Beverley wrote:
However, I still think it would be a neat little feature to be able to write:
my @foo = param 'foo'
(a bit like you can with uploads). Would a patch for such a feature be accepted?
At first glance, it's a good idea. I would just have to double-check that it doesn't break anything critical. Like, I'm thinking that code that does my @params_i_want = map { param($_) } qw/ foo bar baz /; would suddenly behave differently. We might either have to only enable that feature if a specific version of Dancer is required and/or issue a deprecation notice. In all cases, please feel free to open an issue and push in some code, and I'll join the fray there. :-) Joy, `/anick PS: those are all pre-coffee thoughts. Caveat Emptor.
Yanick Champoux <yanick@babyl.dyndns.org> wrote:
On 14-08-22 06:25 AM, Andrew Beverley wrote:
However, I still think it would be a neat little feature to be able to write:
my @foo = param 'foo'
(a bit like you can with uploads). Would a patch for such a feature be accepted?
At first glance, it's a good idea. I would just have to double-check that it doesn't break anything critical. Like, I'm thinking that code that does
my @params_i_want = map { param($_) } qw/ foo bar baz /;
would suddenly behave differently.
I think a change of this sort would be a fairly bad idea, to be honest. There's lots of reasonable code that would suddenly break if param() changed from returning a single value in list context to returning a possibly-empty list. You've given one example here; another is (say): my $searcher = SearchEngine->new( query => param('q'), lang => param('lang'), ); I discussed these issues (including context-sensitivity in specifically a param()-like routine) at some length in a talk at YAPC::EU a couple of years ago: http://aaroncrane.co.uk/talks/calamitous_context/ That said, I do understand why someone would want to be able to get a list of all the values for a given parameter name. Instead of changing the predictable behaviour of param(), I'd suggest adding a new routine that does precisely what you want, perhaps along these lines: sub param_list { my ($name) = @_; croak "param_list() must be called in list context" if !wantarray; my $value = param($name) // []; return ref $value eq 'ARRAY' ? @$value : $value; } I think it might also be worth changing param() to return an empty array ref (instead of the undefined value) when there's no parameter of the desired name, but I'm less sure about that. -- Aaron Crane ** http://aaroncrane.co.uk/
On Fri, 2014-08-22 at 13:25 +0100, Aaron Crane wrote: [...]
That said, I do understand why someone would want to be able to get a list of all the values for a given parameter name. Instead of changing the predictable behaviour of param(), I'd suggest adding a new routine that does precisely what you want, perhaps along these lines:
sub param_list { my ($name) = @_; croak "param_list() must be called in list context" if !wantarray; my $value = param($name) // []; return ref $value eq 'ARRAY' ? @$value : $value; }
+1 from me - that would be really useful. Should I raise an issue/pull request? Thanks, Andy
On 14-08-22 01:18 PM, Andrew Beverley wrote:
On Fri, 2014-08-22 at 13:25 +0100, Aaron Crane wrote: [...]
That said, I do understand why someone would want to be able to get a list of all the values for a given parameter name. Instead of changing the predictable behaviour of param(), I'd suggest adding a new routine that does precisely what you want, perhaps along these lines:
sub param_list { my ($name) = @_; croak "param_list() must be called in list context" if !wantarray; my $value = param($name) // []; return ref $value eq 'ARRAY' ? @$value : $value; }
+1 from me - that would be really useful.
Indeed, and Aaron speaks wisdom. Better have a new 'param_list' (or 'param_array'?) and leave the current 'param' alone. That should makes everyone happy.
Should I raise an issue/pull request?
Please do! Joy, `/anick
On 14-08-23 12:03 PM, Yanick Champoux wrote:
Should I raise an issue/pull request?
Please do!
Beat you to it. ;-) https://github.com/PerlDancer/Dancer/pull/1055 Joy, `/anick
On Sat, 2014-08-23 at 15:22 -0400, Yanick Champoux wrote:
On 14-08-23 12:03 PM, Yanick Champoux wrote:
Should I raise an issue/pull request?
Please do!
Beat you to it. ;-)
Oh, thank you ;-) Much appreciated, Andy
participants (5)
-
Aaron Crane -
Andrew Beverley -
James Baer -
Maxwell Carey -
Yanick Champoux