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

Monks good day! I have a coding problem... and I need your advice.

I am using HTML::Template module. In my CGI script, I am calling a subloop inside the main loop. I wanted an output that's something like this:

Topic 1 - Item A - Item B - Item C Topic 2 - Item X - Item Y - Item Z Topic 3 - Item a - Item b - Item c
but instead, my code resulted to:
Topic 1 - Item a - Item b - Item c Topic 2 - Item a - Item b - Item c Topic 3 - Item a - Item b - Item c
Here's a part of my code:
$y = 0; @loop = (); while($y < $x) { my %items; $items{_TOPIC} = $topic[$y]; $sth = $dbh->prepare("SELECT item1, item2, item3 FROM table WHERE +topic='$topic[$y]' ORDER BY id ASC"); $sth->execute(); @subloop = (); while(@ary = $sth->fetchrow_array()) { my %subitems; $subitems{_first_item} = $ary[0]; $subitems{_second_item} = $ary[1]; $subitems{_third_item} = $ary[2]; push(@subloop, \%subitems); } $items{_ITEMS} = \@subloop; push(@loop, \%items); $y++; } $html->param(_TOPICS => \@loop); $html->output;
Can you help me point out the error?

Replies are listed 'Best First'.
Re: CGI Coding Problem on Subloop
by davidrw (Prior) on Jun 17, 2006 at 20:36 UTC
    don't see the error offhand yet, but do have some code comments/suggestions after a qiuck read..
    use strict; # use em if use warnings; # you're not already my @loop; # first, prepare the SQL .. this can be more efficient. # BUT more importantly, this also is using placeholders # ALSO note the column aliases .. this makes things more convenient +below. my $sth = $dbh->prepare("SELECT item1 as _first_item, item2 as _seco +nd_item, item3 as _third_item FROM table WHERE topic = ? ORDER BY id +ASC"); # no need for a $y index .. foreach my $topic ( @topic[0 .. $x-1] ){ # just use an array slice +to get the topics $sth->execute( $topic ); # passing a value to the placeholder push @loop, { _TOPIC => $topic, _ITEMS => $sth->fetchall_arrayref({}), # use a DBI function to + get the AoH of items }; } $html->param(_TOPICS => \@loop); $html->output;
    Hopefully clearing up the code i little w/some of those suggestions will make the bug more apparent ..

    Can you also post the template source that your code is using?


    update: can further simplify to a map statment:
    my $sth = $dbh->prepare("SELECT item1 as _first_item, item2 as _seco +nd_item, item3 as _third_item FROM table WHERE topic = ? ORDER BY id +ASC"); my @loop = map { $sth->execute( $_ ); { _TOPIC => $_, _ITEMS => $sth->fetchall_arrayref({}) }; } @topic[0 .. $x-1];
Re: CGI Coding Problem on Subloop
by japhy (Canon) on Jun 17, 2006 at 21:00 UTC
    The problem is that @subloop is the same array each time. Instead of @subloop = ();, use my @subloop;. Either that, or change $items{_ITEMS} = \@subloop; to $items{_ITEMS} = [@subloop];.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart