in reply to Dancer2 parameters understanding and usage

Hi Discipulus,

The main problem you have with the posted code is that you are trying to retrieve the value of your body parameters with the method for retrieving query parameters.

When you get data POSTed from a form, it's transported in the body of the HTTP request (in general, not specific to Dancer). Query parameters are those passed as the query string, e.g. /form?search_for=truth.

Dancer2 provides various ways to access your parameters.

The three methods for retrieving a certain class of params, body_parameters(), query_parameters(), route_parameters() all return a Hash::MultiValue object, so it is necessary to call a method to get values.

The reason for using Hash::MultiValue, and the reason these methods are recommended in the Dancer2 doc, is so you can, well, have multiple values. This is most commonly seen in query params, e.g.:

/form?multival=bar&multival=baz
To get all the values for multival you would use:
my @values = query_parameters->get_all('multival');
(see Hash::MultiValue).

The documentation for Dancer2 is, like most of the large frameworks, extensive and somewhat tricky to navigate. But it's all there in the manual:

Also:

I made a new pull request to your Github repo incorporating all the above suggestions into your app. The relevant route handler code is shown below.

Hope this helps!

any ['get', 'post'] => '/form' => sub { # POST request if ( request->method() eq "POST" ) { debug "method: POST"; debug 'All params: ' . Dumper { params }; debug 'One param from href: ' . params->{'search_for'}; debug 'Form params: ' . Dumper body_parameters->mixed; + # see Hash::MultiValue debug 'Param "search_for": ' . body_parameters->get('search_f +or'); debug 'Another way: ' . param 'search_for'; template 'form' => { title => 'Form Test', headline => 'form test POST', form_url => '/form', search_for => param 'search_for', # least typing ;-) }; } # GET request else { template 'form' => { title => 'Form Test', headline => 'formtest GET', form_url => '/form', }; } };


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: Dancer2 parameters understanding and usage
by Discipulus (Canon) on Nov 29, 2017 at 16:16 UTC
    Hello 1nickt++ and ++1nickt (even if we know this leads to an undefined behaviour..)

    > The main problem you have with the posted code is that you are trying to retrieve the value of your body parameters with the method for retrieving query parameters.

    > When you get data POSTed from a form, it's transported in the body of the HTTP request (in general, not specific to Dancer). Query parameters are those passed as the query string, e.g. /form?search_for=truth.

    OMG i completely misunderstood the terminology and I repeat, docs have not helped me a lot. I was sure (nothing worst to be convinced of something wrong) that query parameters were these passed via POST and body ones were something defined in the body of the routes, like private variables..

    My approsimative understanding of the web mechanism (i'd say underlying form) does not revealed immediatly to me that query parameters was for things passed via query in the URL like /form?search_for=truth and that body ones were reffered to the body of the incoming POSTed request.

    I also misunderstood route parameters at first glance: i've tested them many times with URLS like /form?search_for=truth before understending that the correct way is:

    get '/routeparam/:name?' => sub { # ok http://127.0.0.1:5000/routeparam/here_my_name "Hey " . route_parameters->get('name') . ", welcome here!"; };

    All your others suggestions and contributions are precious for me.

    I have already read all the docs you linked above but i'm even more convinced now that basic docs need some integrations for not already web developpers. As soon as I have got all these basic dance moves I'll make a pr for the doc part of Dancer2 probably for the main manual.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Just to be clear about route parameters. You can define any part of a URL path as a parameter. You don't need a 'static' part to prefix a param, although a lot of apps, particularly REST APIs, do that. You can also use route and query (and even body) params together. For example:

      get '/foo/:name/bar/:age/:occupation' => sub { return '<pre>'.Dumper({ params }).'</pre>'; };
      If the user requests the following URL:
      http://localhost:5000/foo/Discipulus/bar/42/student?country=Eataly&cit +y=Roma
      The app displays in the browser:
      <pre>$VAR1 = { 'name' => 'Discipulus', 'age' => '42', 'city' => 'Roma', 'occupation' => 'student', 'country' => 'Eataly' }; </pre>

      Also see: Dancer2 Advent Calendar: New Parameters Keywords. (The Dancer2 Advent Calendar is a great source of documentation and examples.)


      The way forward always starts with a minimal test.