Home > Net >  How to post multiple flash messages using Mojolicious
How to post multiple flash messages using Mojolicious

Time:08-20

Is it possible to have more than one flash message at a time under Mojolicious? I have a case where a form can have multiple errors, and I want to be able to list all the error messages at once, instead of finding one error, displaying one error, having the user fix one error, repeat for the other errors.

In this example where messages are set in one page, and then displayed in another, only the last message added is shown.

get '/' => sub {
    my ($c) = @_; 

    $c->flash(msg => "This is message one.");
    $c->flash(msg => "This is message two.");
    $c->flash(msg => "This is message three.");
    $c->flash(msg => "This is message four.");
    $c->flash(msg => "This is message five.");
    return $c->redirect_to('/second');
};

get '/second' => sub {
    my ($c) = @_; 

    return $c->render(template => 'second');
};

app->secrets(["aren't important here"]);
app->start;

__DATA__
@@ second.html.ep
<!doctype html><html><head><title>Messages</title></head>
<body>
These are the flash messages:
<ul>
  % if (my $msg = flash('msg')) {
  <li><%= $msg %></li>
  % }
</ul>
</body></html>

The output is

These are the flash messages:

    This is message five.

I have also tried fetching the messages in list context, but still only the last message is displayed.

__DATA__
@@ second.html.ep
<!doctype html><html><head><title>Messages</title></head>
<body>
These are the flash messages:
<ul>
  % if (my @msg = flash('msg')) {
  %   foreach my $m (@msg) {
  <li><%= $m %></li>
  %   }
  % }
</ul>
</body></html>

Thank you.

CodePudding user response:

Flash data is stored in a hash. You are overwriting the value for key 'msg' each time you call flash(). You can use flash to store a data structure instead of a scalar value:

use Mojolicious::Lite -signatures;

get '/' => sub {
    my ($c) = @_; 
    my @messages = map ("This is message $_", qw/one two three four/);
    $c->flash(msg =>\@messages);
    return $c->redirect_to('/second');
};

get '/second' => sub {
    my ($c) = @_; 
    return $c->render(template => 'second');
};

app->secrets(["aren't important here"]);
app->start;

__DATA__
@@ second.html.ep
<!doctype html><html><head><title>Messages</title></head>
<body>
These are the flash messages:
<ul>
  % for my $msg  (@{flash('msg')//[]}) {
  <li><%= $msg %></li>
  % }
</ul>
</body></html>
  • Related