Oneill
Oneill

Reputation: 339

Result of request not show in Template Toolkit

I have an SQLite database with computer table. I have two rows in computer table.

I want to get all computers and show the results in Template Toolkit template.

This is the Dancer2 controller code, which uses Dancer2::Plugin::Auth::Tiny and Dancer2::Plugin::DBIC

get '/listallmachine' => needs login => sub {
    my $computerRs = schema('default')->resultset('Computer');
    my @computers = $computerRs->all;
    template 'listmachine' => {
        'title'     => 'Liste des machines',
        'msg'       => get_flash(),
        'computers' => \@computers
    };
 }; 

And for the template:

[% FOREACH c IN computers %]
    <tr>
        <td>[% c.ip %]</td>
        <td>[% c.uuid %]</td>
    </tr>
[% END %]

Configuration file:

# configuration file for development environment

# the logger engine to use
# console: log messages to STDOUT (your console where you started the
#          application server)
# file:    log message to a file in log/
logger: "console"

# the log level for this environment
# core is the lowest, it shows Dancer2's core log messages as well as yours
# (debug, info, warning and error)
log: "core"

# should Dancer2 consider warnings as critical errors?
warnings: 1

# should Dancer2 show a stacktrace when an 5xx error is caught?
# if set to yes, public/500.html will be ignored and either
# views/500.tt, 'error_template' template, or a default error template will be used.
show_errors: 1

# print the banner
startup_info: 1

plugins:
      DBIC:
        default:
          dsn: dbi:SQLite:dbname=papt.db

The template shows nothing. Have you any idea?

Upvotes: 0

Views: 285

Answers (2)

Dave Cross
Dave Cross

Reputation: 69314

You need to take a reference to @computers.

get '/listallmachine' => needs login => sub {
    my $computerRs = schema('default')->resultset('User');
    my @computers=$computerRs->all;
    template 'listmachine' => {
        'title'     => 'Liste des machines',
        'msg'       => get_flash(),
        'computers' => \@computers, # Note: Take reference here.
    };
};

Update: Ok, I think I can explain this now.

In a comment, you say that get_flash() returns "a Hashmap" (which, I assume, means "a hash"). Let's assume that it returns a hash with two key/value pairs (one => 1 and two => 2). That means that the hash you send to template will look like this:

{
  title     => 'Liste des machines',
  msg       => one => 1, two => 2,
  computers => \@computers
};

But that's all just a flat list. Perl will interpret it like this:

{
  title       => 'Liste des machines',
  msg         => 'one',
  1           => 'two',
  2           => 'computers',
  \@computers => undef,
};

Do you see what has happened? Because of the multiple values returned from get_flash() your key/value pairs have all got out of line. And you no longer have a hash key called computers. That's why the template can't find a variable called computers - it no longer exists.

The fix is to take a reference to the hash that is returned from get_flash():

{
  title     => 'Liste des machines',
  msg       => { get_flash() },
  computers => \@computers
};

The reference prevents the hash being flattened into a list. Your data structure will look like this:

{
  title     => 'Liste des machines',
  msg       => { one => 1, two => 2 },
  computers => \@computers
};

(Pedantically, the problem is that subroutines don't return hashes - they return lists. The list only becomes a hash when you store it in a hash variable.)

Upvotes: 2

Oneill
Oneill

Reputation: 339

Ok I understood the problem. This is my get_flash() function, indeed when I remove the "msg" element the showing is ok. So I have forget my reference and the "get_flash" function is bad. Thanks you for your help.

Upvotes: 0

Related Questions