One more thing: you need to keep a strong reference to the Mojo::UserAgent object until it completes, so you should define $ua outside of the action method which will end before the async code occurs.
-Dan On Thu, Feb 7, 2019 at 1:23 PM Dan Book <gri...@gmail.com> wrote: > Your commented 'for' loop is correct; you need to dereference > stash('titles') to pass the list of hashrefs to the loop. The other problem > is that you need to prevent auto-rendering until your async code has > completed. You can do this by calling `$c->render_later` at the beginning > of the action (`$c` is the first argument passed to the action, which you > need to retrieve), and then `$c->render` after you've set the stash value. > You can even include the stash update in the render call: > `$c->render(titles => $titles);` > > I would additionally recommend to use promises rather than delays as it > will lead to much more concise code with the promise methods available from > Mojo::UserAgent. Also, you want to hold a reference to the transaction, and > add exception handling, as described here: > https://github.com/mojolicious/mojo/wiki/Upgrading#delay-helper-removed > > Here is how it might look as a start: > > get '/titles' => sub { > my $c = shift; > $c->render_later; > my $tx = $c->tx; > my $ua = Mojo::UserAgent->new; > my @promises = map { $ua->get_p($_) } @urls; > Mojo::Promise->all(@promises)->then(sub { > my @results = @_; > my $titles = []; > foreach my $result (@results) { > my $tx = $result->[0]; > my $title = trim($tx->res->dom->at('title')->text); > push @$titles, {host => $tx->req->url->host, title => $title}; > } > $c->render(titles => $titles); > })->catch(sub { $c->reply->exception(pop); undef $tx }); > } => 'titles'; > > -Dan > > On Thu, Feb 7, 2019 at 12:57 PM Ron Bergin <rkber...@gmail.com> wrote: > >> Note: I cross posted this question on perlmonks >> https://perlmonks.org/?node_id=1229558 >> >> On Thursday, February 7, 2019 at 9:48:20 AM UTC-8, Ron Bergin wrote: >>> >>> I'm brand new to Mojolicious and working on a lite script that goes to >>> 75 urls and retrieves text in an h3 tag. I've worked up a working test >>> script that outputs to console and now I'm working on adjusting it to be a >>> web app but I can't seem to get the correct syntax to store/retrieve the >>> data. What am I doing wrong? >>> >>> #!/usr/bin/perl >>> >>> use Mojolicious::Lite; >>> >>> my @urls = ( >>> 'https://mojolicious.org', >>> 'https://metacpan.org', >>> 'https://perlmonks.org', >>> 'http://www.google.com', >>> ); >>> >>> get '/titles' => sub { >>> my $ua = Mojo::UserAgent->new; >>> my $async = Mojo::IOLoop::Delay->new; >>> >>> $async->steps( >>> sub { >>> my $self = shift; >>> $ua->get($_, $self->begin) for @urls; >>> }, >>> sub { >>> my ($self, @tx) = @_; >>> my $titles = []; >>> >>> foreach (@tx) { >>> my $title = ''; >>> my $status = $_->res->is_success ? 'Connected' : $_-> >>> error->{message}; >>> >>> if ( $_->res->is_success ) { >>> $title = $_->res->dom->at('title')->text; >>> $title =~ s/^\s+|\s+$//g; # couldn't get Mojo::Util >>> trim function to work >>> } >>> >>> push @$titles, {host => $_->req->url->host, status => >>> $status, title => $title}; >>> } >>> $self->stash(titles => $titles); >>> } >>> ); >>> } => 'titles'; >>> >>> app->start; >>> >>> __DATA__ >>> >>> @@ titles.html.ep >>> % layout 'titles'; >>> >>> %= dumper stash('titles') >>> >>> <table border=1> >>> <tr> >>> <th>Host</th> >>> <th>Status</th> >>> <th>Title</th> >>> </tr> >>> >>> <!-- % for my $server ( @{ stash('titles') } ) { --> >>> % for my $server ( stash('titles') ) { >>> <tr> >>> <td><%= $server->{host} %></td> >>> <td><%= $server->{status} %></td> >>> <td><%= $server->{title} =%></td> >>> </tr> >>> % } >>> </table> >>> >>> @@ layouts/titles.html.ep >>> <!doctype html> >>> >>> <html> >>> >>> <head> >>> <title>Titles</title> >>> </head> >>> >>> <body> >>> <h1>Titles</h1> >>> <%= content =%> >>> </body> >>> >>> </html> >>> >>> >>> Here's the output: >>> >>>> $ ./titles_web.pl get /titles >>>> [Thu Feb 7 09:45:54 2019] [debug] GET "/titles" (fcf21ce8) >>>> [Thu Feb 7 09:45:54 2019] [debug] Routing to a callback >>>> [Thu Feb 7 09:45:54 2019] [debug] Rendering template "titles.html.ep" >>>> from DATA section >>>> [Thu Feb 7 09:45:54 2019] [debug] Rendering template >>>> "layouts/titles.html.ep" from DATA section >>>> [Thu Feb 7 09:45:54 2019] [debug] 200 OK (0.00267s, 374.532/s) >>>> <!doctype html> >>>> >>>> <html> >>>> >>>> <head> >>>> <title>Titles</title> >>>> </head> >>>> >>>> <body> >>>> <h1>Titles</h1> >>>> >>>> undef >>>> >>>> >>>> <table border=1> >>>> <tr> >>>> <th>Host</th> >>>> <th>Status</th> >>>> <th>Title</th> >>>> </tr> >>>> >>>> <!-- % for my $server ( @{ stash('titles') } ) { --> >>>> <tr> >>>> <td></td> >>>> <td></td> >>>> <td></td> >>>> </tr> >>>> </table> >>>> </body> >>>> >>>> </html> >>>> >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "Mojolicious" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to mojolicious+unsubscr...@googlegroups.com. >> To post to this group, send email to mojolicious@googlegroups.com. >> Visit this group at https://groups.google.com/group/mojolicious. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "Mojolicious" group. To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious+unsubscr...@googlegroups.com. To post to this group, send email to mojolicious@googlegroups.com. Visit this group at https://groups.google.com/group/mojolicious. For more options, visit https://groups.google.com/d/optout.