Question

I have a site running Dancer.

In this site, i have a form with one textarea, and foreach line written in this textarea, when the form is submitted via post, i do some action for it. Each line starts a process, and it takes some time ( depending of the line, the process can take about 20 secs, 40 secs, 1 minute... )

The post is something like this:

post '/actions/AddSrv' => sub {  
    my $self = shift;
    my @Results;
    foreach my $dest_addr ( split /\n/, params->{HostsList} ){
        #Here starts the process
        my $Result = start_some_process($dest_addr);
        push @Results, $Result;
        ##Now i have the result of this process execution
    }
    template 'actions/AddSrv.tt', { Results => [ @Results ] }, { layout => 'logged_site' };
};

with this code, I need to wait until all $dest_addr are processed to view in the screen the result of all executions. Exists a way to print inmediatly the result of each process when the call to start_some_process() ends? Now I need to wait until the foreach ends, to return the template

How can I achieve something like this?

Was it helpful?

Solution

Unfortunately no there is not a way to return the template as soon as you receive the first response and show the results of each process within that same page load on the browser. You want to use Ajax for this. The form will post via Ajax to your route and handle the return data through the Ajax call. This data is typically JSON formatted and Dancer has a great plugin for Ajax routes.

If you go with this method you first build the AJAX based route that the form will post to:

ajax '/actions/AddSrv' => sub {
            my $self = shift;
    my @Results;
    foreach my $dest_addr ( split /\n/, params->{HostsList} ){
        #Here starts the process
        my $Result = start_some_process($dest_addr);
        push @Results, $Result;
        ##Now i have the result of this process execution
        ## Insure your data is in a hash or array and encode to JSON
        my $json_text = to_json(\%results);
        return $json_text;

    }
};

Next you create the GET request route which simply serves the template that includes the form and AJAX handler to the end-user. Please note this can be named the same as the above route, but it will have to be AFTER the AJAX route in the route chain. The AJAX handler will pass to this route when the user accesses that url as the requests header X-Requested-With doesn't equal XMLHttpRequest (AJAX Call)

get '/actions/AddSrv' => sub {  
    template 'actions/AddSrv.tt', { layout => 'logged_site' };
};

Finally you will include Javascript within script tags on your template that contains the Ajax handler. The Ajax handler will parse the information from the form's input text area and send each line as an individual Ajax call and await a response. Once it receives a response for that input line it has the return data in the JSON object and you can render it on your page. This will continue until each Ajax call returns the desired data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top