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

Am trying to get my output of data to this format

({ "items": [ { "title": "Valls" }, { "title": "AUT15605" }, { "title": "10UT15605" } ] })

Am getting this error with my code

Can't modify private hash in concatenation (.) or string
my $dbh = DBI->connect("DBI:mysql:$dbname:$host", $usr, $pwd, { RaiseError => 1, }) or die $DBI::errstr; my $sth = $dbh->prepare("SELECT titles FROM tbl_1"); $sth->execute(); my $Data = $sth->fetchall_arrayref(); my %output; foreach my $Data (@$Data) { my ($title) = @$Data; %output .= ( 'items' => [("title" => "$title")] ); } my $results = to_json(\%output); print "Content-type: text/html\n\n"; print $results;

Replies are listed 'Best First'.
Re: Returning data
by jeffenstein (Hermit) on Apr 20, 2024 at 20:48 UTC

    Here, string contcatenation doesn't work with hashes

    %output .= ( 'items' => [("title" => "$title")] );

    I'm guessing you want something like this:

    $output{items} ||= []; push @{$output{items}}, {title => $title};

    You should probably take a look at perldsc to see how you can use nested hashes & arrays

    Also, the content type here should most likely be 'application/json'

    print "Content-type: text/html\n\n"; print $results;

    🐪

        am still getting the same error even if i use that module

        Can't modify private hash in concatenation (.) or string

      am getting this error: cannot encode reference to scalar 'SCALAR(0x55c89ffbc4f0)' unless the scalar is 0 or 1

      my $dbh = DBI->connect("DBI:mysql:$dbname:$host", $usr, $pwd, { RaiseError => 1, }) or die $DBI::errstr; my $sth = $dbh->prepare("SELECT titles FROM tbl_1"); $sth->execute(); my $Data = $sth->fetchall_arrayref(); my $output; foreach my $Data (@$Data) { my ($title) = @$Data; $output{items} ||= []; push @{$output{items}}, {title => $title}; } my $encoded = encode_json \$output; print $Cgi->header( -type => 'application/json' ),$encoded;
Re: Returning data
by Marshall (Canon) on Apr 21, 2024 at 10:25 UTC
    It looks like you have the part that gets the titles from the DB correct. Consider this:
    use strict; use warnings; use 5.10.0; use JSON; use Data::Dump qw(pp); my %output; foreach my $title ("Valls", "AUT15605", "10UT15605") { push @{$output{items}}, {title => $title}; } my $output_json = encode_json \%output; say $output_json; pp \%output; __END__ This is what the Perl structure looks like: { items => [ { title => "Valls" }, { title => "AUT15605" }, { title => "10UT15605" }, ], } This is the encoded JSON: {"items":[{"title":"Valls"},{"title":"AUT15605"},{"title":"10UT15605"} +]}
    "items" is a hash key which has a value that is a reference to an array of anon hashes.

      thanks this has worked for me

Re: Returning data
by johngg (Canon) on Apr 20, 2024 at 20:53 UTC
    %output .= (

    should perhaps be

    %output = (

    I haven't looked at the overall logic of what you are doing but that leaps out of the page!

    Cheers,

    JohnGG

      this returns 1 row

      this returns {"items":"title","Jo0993"}

      this is the format i want

      ({ "items": [ { "title": "Valls" }, { "title": "AUT15605" }, { "title": "10UT15605" } ] })

      My Try on ur suggestion

      my $dbh = DBI->connect("DBI:mysql:$dbname:$host", $usr, $pwd, { RaiseError => 1, }) or die $DBI::errstr; my $sth = $dbh->prepare("SELECT titles FROM tbl_1"); $sth->execute(); my $Data = $sth->fetchall_arrayref(); my %output; foreach my $Data (@$Data) { my ($title) = @$Data; %output = ( 'items' => [("title" => "$title")] ); } my $encoded = encode_json \%output; print $Cgi->header( -type => 'application/json' ),$encoded;
Re: Returning data
by BillKSmith (Monsignor) on Apr 21, 2024 at 21:23 UTC
    The following code explicitly stores the list of hash refs into the array referenced by $output{items}.
    use strict; use warnings; use Data::Dumper; my $Data = # simulated output of fetchall_arrayref() [ [ 'Valls', ('more fields')], [ 'AUT15605', ('more fields')], [ '10UT15605', ('more fields')], ]; my %output; @{$output{items}} = map { {title => $_->[0]} } @$Data; print Dumper(\%output);
    Bill
Re: Returning data
by TheloniusMonk (Sexton) on Apr 22, 2024 at 12:13 UTC
    I'd use the JSON module rather than try to homegrow it.