Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

CGI::Application, the cgiapp_prerun mode, and CGI object interaction

by geektron (Curate)
on Oct 16, 2005 at 22:52 UTC ( [id://500619]=perlquestion: print w/replies, xml ) Need Help??

geektron has asked for the wisdom of the Perl Monks concerning the following question:

I found a strange behaviour in a CGI::Application-based app. I use  cgiapp_prerun to call my storage methods from the previous page. If a new whatever gets stored (rather than performing an update on the "whatever") I need that ID ( a mysql_insertid on the next page of the application.

I've tried setting the new ID in the CGI object (via  $self->query->param( -name = 'whatever', -value => 123);, but between the sub-object call and the run_mode call, the parameter isn't set.

I've tried setting the same "whatever" as a CGI::App param (using $self->param( 'whatever', 123 );) to no avail also.

I'd think that CGI::App uses a singleton appoach for the CGI (and HTML::Template) would be used, and when I've examined the code previously my opinion is supported. I've looked at the stringified reference string for the CGI object, and it looks the same.

Why wouldn't I be getting the "whatever" parameter in the runmode?

Replies are listed 'Best First'.
Re: CGI::Application, the cgiapp_prerun mode, and CGI object interaction
by cees (Curate) on Oct 17, 2005 at 01:12 UTC

    Your question is not very clear, and I think it would help a lot if you showed some code.

    That having been said, when setting a parameter using CGI.pm, you need to know that CGI.pm does not override existing parameters unless you tell it to. So if 'whatever' is already a parameter, and you want CGI.pm to change it, you need to pass it the -override => 1 option to your call to param.

    The same thing shouldn't be happening when using the CGI::Application param method (which has absolutely no relation to the CGI.pm param method). So since you are not seeing the parameter you set in your runmode, then I have to think it was a coding mistake on your part, or you are expecting this info to stay persistent across multiple browser requests. Since you are taking about 'previous page' and 'next page', I am guessing that your problem is with persistence.

    The first thing I would check is to make sure that your cgiapp_prerun is actually being executed during the request. Have you put a print statement in there to confirm that it is running?

    Failing that, try using the CGI::Application::Plugin::Session plugin which will give you a session that is persistent across requests to see if that solves your problem

    use CGI::Application::Plugin::Session; sub cgiapp_prerun { my $self = shift; $self->session->param(whatever => 123); } sub my_runmode { my $self = shift; my $whatever = $self->session->param('whatever'); }
      Guess I didn't step away enough to have it make sense to anyone else....

      That said, here's some code:

      sub cgiapp_prerun { my $self = shift; my $dbh = $self->{DBH} = $self->param('DBH'); ### let's check for storage; my $previousClass = $self->query->param('this'); my $className = "DataClasses::${previousClass}"; if ( $className->SUPER::can( 'new' ) and $className->SUPER::can( 'store') ) { my $object = $className->new( DBH => $dbh, REQUEST => $request ); ## the needStorage method allows us to ## have multiple "screens" using the same class ## where not all of them store in the DB $object->store() if $object->needStorage(); } } }
      and the store() method ...
      sub store { my ( $self, %params )_ = @_; ### if insert ... $self->query->param( -name => 'whatever', -value => '123'); $self->param( 'whatever', '123' ); return 1; }
      both methods of stashing the value until the runmode is executed failed. as i've understood the calling stack:

      CGI::App->new() -> prerun -> setup -> "runmode" -> teardown

      so i don't see how something set in one mode wouldn't carry into another, because it's the same "run cycle".

        My recommendation would be to start trimming your code down until things start working. The way you are calling $self->param(...) should work fine, and that value should be recoverable from within your runmode.

        I'll ask again, are you sure that code is being executed? Try the following and you will see that your concept should work fine. Just save all of it into one file, and run it from the command line:

        #!/usr/bin/perl { package TestApp; use base qw(CGI::Application); use CGI qw(:standard); sub setup { my $self = shift; $self->run_modes([qw(start)]); } sub cgiapp_prerun { my $self = shift; print STDERR "calling cgiapp_prerun\n"; $self->param( test => 123 ); } sub start { my $self = shift; my $test = $self->param('test'); print STDERR "test: $test\n"; return qq{<html><body><h1>test: $test</h1></body></html>}; } } TestApp->new->run;

        I have one more question for you. Do you have the following line in your code somewhere?

        use CGI qw(:standard);

        If so, then remove it and things will most likely start to work for you.

Re: CGI::Application, the cgiapp_prerun mode, and CGI object interaction
by johnnywang (Priest) on Oct 16, 2005 at 23:28 UTC
    I'm not sure I understand your question, are you trying to pass a parameter from one page to another? CGI::Application is not going to keep state for you between runs, you have to do that yourself: use hidden parameters, cookies, sessions or save them somewhere.
      no, it's not saving state between pages.

      cgiapp_prerun and the runmode are called in the same run cycle.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://500619]
Approved by johnnywang
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (2)
As of 2024-04-19 20:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found