Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Help with JSON Module

by foggy3657 (Novice)
on Sep 07, 2012 at 14:28 UTC ( #992320=perlquestion: print w/ replies, xml ) Need Help??
foggy3657 has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I am new to programming and Perl. I am using a an API to return JSON data/array/hash and from that I need to create a variable from part of the data in order to create my next URL. From a previous request for help I have been advised that I should use the JSON module. I have tried to follow an example taken from google, but clearly failing to grasp the program logic or syntax.

#!/usr/bin/perl use warnings; use strict; use WebService::Tesco::API; use JSON; # My code to login removed print "Scan Item...."; my $pn = <>; #Scan Bar Code chop ($pn); # +remove %OA from end of scan code my $code = $tesco->product_search({ searchtext => $pn, extendedinfo => + 'N' }); my $json = JSON->new; my $data = $json->decode($code); my $pid = $data->{Products}[0]{ProductId},"\n"; print $pid,"\n";

Returned is:

Useless use of a constant ( ) in void context at tesc_json1.pl line 22. https://secure.techfortesco.com/groceryapi_b1/restservice.aspx?email=x +xxxx%40yahoo.co.uk&password=xxxxx&developerkey=xxxxxx&applicationkey= +xxxxx&command=LOGIN at /usr/local/share/perl/5.14.2/WebService/Tesco/ +API.pm line 59. { "StatusCode": 0, "StatusInfo": "Command Processed OK", "BranchNumber": "5528", "CustomerId": "20846164", "CustomerName": "Mr Stubbs", "SessionKey": "5VApkMMTjO8LtFCy9VjcSrcZKxoewwHGj6XoUUGaH2fBWf73cU", "InAmendOrderMode": "N", "BasketID": "98911496", "ChosenDeliverySlotInfo": "No delivery slot is reserved.", "CustomerForename": "James" } Scan Item....5000175411118 http://www.techfortesco.com/groceryapi_b1/restservice.aspx?searchtext= +5000175411118&extendedinfo=N&sessionkey=5VApkMMTjO8LtFCy9VjcSrcZKxoew +wHGj6XoUUGaH2fBWf73cU&command=PRODUCTSEARCH at /usr/local/share/perl/ +5.14.2/WebService/Tesco/API.pm line 59, <> line 1. { "StatusCode": 0, "StatusInfo": "Command Processed OK", "PageNumber": 0, "TotalPageCount": 1, "TotalProductCount": 1, "PageProductCount": 1, "Products": [ { "BaseProductId": "50043662", "EANBarcode": "5000175411118", "CheaperAlternativeProductId": "", "HealthierAlternativeProductId": "", "ImagePath": "http://img.tesco.com/Groceries/pi/118/5000175411118/IDSh +ot_90x90.jpg", "MaximumPurchaseQuantity": 99, "Name": "Oxo 12 Chicken Stock Cubes 71G", "OfferPromotion": "Price Drop Was 1.13 Now 1.00 ", "OfferValidity": "valid from 30/7/2012 until 9/9/2012", "OfferLabelImagePath": "http://www.tesco.com/Groceries/UIAssets/I/Site +s/Retail/Superstore/Online/Product/pos/save.png", "Price": 1, "PriceDescription": "1.41 each", "ProductId": "254881114", "ProductType": "QuantityOnlyProduct", "UnitPrice": 1.41, "UnitType": "100g" } ] } malformed JSON string, neither array, object, number, string or atom, +at character offset 0 (before "HASH(0x1610440)") at tesc_json1.pl lin +e 20, <> line 1.

Clearly I have two (2) errors, despite googling, I am unable figure out what it is I am doing wrong. I would appreciate it if someone could assist.

Thank you - James

Comment on Help with JSON Module
Select or Download Code
Re: Help with JSON Module
by philiprbrenan (Monk) on Sep 07, 2012 at 14:49 UTC
    my $pid = $data->{Products}[0]{ProductId},"\n";

    Comma should be dot

      Thank you, that got rid of one error.

      Any thoughts on the Malformed JSON error at the bottom?

      Best wishes - James

        You are passing something which is not a JSON string to JSON's decode method. In particular, I believe you're passing a hashref.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Help with JSON Module
by philiprbrenan (Monk) on Sep 07, 2012 at 15:05 UTC

    Please consider taking things step by step so that you build up to the solution incrementally rather than trying to take one giant leap at the start.

    use feature ":5.14"; use warnings FATAL => qw(all); use strict; use Data::Dump qw(dump pp); use JSON::PP; my $j = JSON::PP->new; my $d = $j->decode(<<'END'); { "StatusCode": 0, "StatusInfo": "Command Processed OK", "BranchNumber": "5528", "CustomerId": "20846164", "CustomerName": "Mr Stubbs", "SessionKey": "5VApkMMTjO8LtFCy9VjcSrcZKxoewwHGj6XoUUGaH2fBWf73cU", "InAmendOrderMode": "N", "BasketID": "98911496", "ChosenDeliverySlotInfo": "No delivery slot is reserved.", "CustomerForename": "James" } END pp($d)

    Produces:

    { BasketID => 98911496, BranchNumber => 5528, ChosenDeliverySlotInfo => "No delivery slot is reserved.", CustomerForename => "James", CustomerId => 20846164, CustomerName => "Mr Stubbs", InAmendOrderMode => "N", SessionKey => "5VApkMMTjO8LtFCy9VjcSrcZKxoewwHGj6XoUUGaH +2fBWf73cU", StatusCode => 0, StatusInfo => "Command Processed OK", }

      Sorry you have lost me. If I add (<<'END'). Then all of the code below changes colour and I'm going to assume it will not run.

      The last bit of code

      my $code = $tesco->product_search({ searchtext => $pn, extendedinfo => + 'N' });

      Returns:

      { "StatusCode": 0, "StatusInfo": "Command Processed OK", "PageNumber": 0, "TotalPageCount": 1, "TotalProductCount": 1, "PageProductCount": 1, "Products": [ { "BaseProductId": "50043662", "EANBarcode": "5000175411118", "CheaperAlternativeProductId": "", "HealthierAlternativeProductId": "", "ImagePath": "http://img.tesco.com/Groceries/pi/118/5000175411118/IDSh +ot_90x90.jpg", "MaximumPurchaseQuantity": 99, "Name": "Oxo 12 Chicken Stock Cubes 71G", "OfferPromotion": "Price Drop Was 1.13 Now 1.00 ", "OfferValidity": "valid from 30/7/2012 until 9/9/2012", "OfferLabelImagePath": "http://www.tesco.com/Groceries/UIAssets/I/Site +s/Retail/Superstore/Online/Product/pos/save.png", "Price": 1, "PriceDescription": "1.41 each", "ProductId": "254881114", "ProductType": "QuantityOnlyProduct", "UnitPrice": 1.41, "UnitType": "100g" } ] }

      Apologies if I am appearing to be stupid.

        This works and returns the correct data "254881114". But I don't see how this helps with my program?

        #!/usr/bin/perl use feature ":5.14"; use warnings FATAL => qw(all); use strict; use Data::Dump qw(dump pp); use JSON::PP; my $j = JSON::PP->new; my $d = $j->decode(<<'END'); { "StatusCode": 0, "StatusInfo": "Command Processed OK", "PageNumber": 0, "TotalPageCount": 1, "TotalProductCount": 1, "PageProductCount": 1, "Products": [ { "BaseProductId": "50043662", "EANBarcode": "5000175411118", "CheaperAlternativeProductId": "", "HealthierAlternativeProductId": "", "ImagePath": "http://img.tesco.com/Groceries/pi/118/5000175411118/IDSh +ot_90x90.jpg", "MaximumPurchaseQuantity": 99, "Name": "Oxo 12 Chicken Stock Cubes 71G", "OfferPromotion": "Price Drop Was 1.13 Now 1.00 ", "OfferValidity": "valid from 30/7/2012 until 9/9/2012", "OfferLabelImagePath": "http://www.tesco.com/Groceries/UIAssets/I/Site +s/Retail/Superstore/Online/Product/pos/save.png", "Price": 1, "PriceDescription": "1.41 each", "ProductId": "254881114", "ProductType": "QuantityOnlyProduct", "UnitPrice": 1.41, "UnitType": "100g" } ] } END pp($d); my $pid; $pid = $d->{Products}[0]{ProductId}."\n"; print $pid,"\n";
Re: Help with JSON Module
by kcott (Abbot) on Sep 08, 2012 at 06:55 UTC

    G'day James,

    I see ++philiprbrenan has solved the Useless use of a constant ... problem.

    For the malformed JSON ... problem, it might be better to look at your input JSON rather than what's being output with the error message. Try:

    my $code = $tesco->product_search({ searchtext => $pn, extendedinfo => + 'N' }); print $code, "\n"; exit;

    You might be able to see the problem by inspection; if not, try running it through the validator you mentioned earlier.

    [Aside: I'll just point out that chomp is a safer version of chop. Of course, you might have a perfectly valid reason for choosing chop.]

    -- Ken

      Thank you for trying to help.

      All your code returns is HASH(0x9fbf738)

      I have tried the validator and it definitely returns Valid.

      I can't help thinking that my JSON decode syntax is incorrect somehow.

      Best wishes - James

        And there's your problem identified.

        JSON's decode method has this syntax:

        $perl_scalar = $json->decode($json_text)

        but you're invoking it as:

        $perl_scalar = $json->decode($hash_reference)

        Use Data::Dumper to determine what data the hash reference points to. Perhaps your JSON string is in there somewhere.

        -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://992320]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2014-12-27 21:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls