views:

57

answers:

1

Hi Guys,

I wonder if anybody could provide me with any assistance to the following problem I am having with my JS project?

I basically have information about a product being pulled from out from 3 different JSP lists:

  • A Product's Details
  • A Products's Ratings
  • A Products's Retailers

What I am trying to a do is loop through the JSP three lists, pulling out the relevant info for each of the products and then create a Javascript object which holds all the product information together.

Once created I then need to loop through this Javascript object and display each product's information on screen - there could be 10, 20, etc, products at a time.

The area I am having trouble with is that when I create my 'mainResults' object (see my code snippet below), although it is being populated correctly, I get a blank array first and then the product arrays after that.

Below is a screenshot from Firebug that shows the an extract from the 'mainResults' javascript object - it is the empty arrays show that are my issue:

link text

This is causing me problems when I try to loop through the 'mainResults' using its length property as it is always reurned as '0'.

I am sure there is better way to achieving what I need to do but after a lot of searching and playing around with OOP I still can't find a good solution.

There are a couple of important things I need to add:

  • I will never know exactly how many products there will be.
  • The products have up to 3 ratings each.
  • I will never know exactly how many retailers a products has.
  • I need to access the product, its ratings and retailers by an index

I have posted the relevant parts of my code below - I really hope somebody can point me in the right direction :)

Many thanks in advance,

Jim

<body onLoad="populate()">
<jsp:useBean id="products" scope="request" class="com.sslpost.mpr.pricerunner.Products" />

    <% if(request.getAttribute("products") != null) 
    products = (Products)request.getAttribute("products"); %>

<script language="JavaScript" type="text/javascript">
    function populate(){
        <% if(products != null) { %>

        //Access Products from JSP Product Class        

        <% for (int i=0; i<products.productsList.size(); i++) {
        Product currProd = products.productsList.get(i);

        //Check Product Id is Not Empty and Handle Accordingly
        String prodId = "";
        if(products.productsList.get(i).id != 0)
            { prodId = Integer.toString(products.productsList.get(i).id); }
        else{ prodId = Integer.toString(0); }

        //Check Product Name is Not Empty and Handle Accordingly
        String prodName = "";
        if(products.productsList.get(i).name != null)
            prodName = products.productsList.get(i).name;

        //Check Product Manufacturer is Not Empty and Handle Accordingly
        String prodManufacturer = "";
        if(products.productsList.get(i).manufacturer != null)
            prodManufacturer = products.productsList.get(i).manufacturer;

        //Check Product Description is Not Empty and Handle Accordingly
        String prodDescription = "";
        if(products.productsList.get(i).description != null)
            prodDescription = products.productsList.get(i).description;

        //Check Product Retailer is Not Empty and Handle Accordingly
        String prodRetailer = "";
        if(products.productsList.get(i).numberOfRetailers != 0)
            { prodRetailer = Integer.toString(products.productsList.get(i).numberOfRetailers); }
        else{ prodRetailer = Integer.toString(0); }

        //Check Product Logo + Height and Width Attributes are Not Empty and Handle Accordingly
        String prodLogo = "";
        if(products.productsList.get(i).imageUrl != null && products.productsList.get(i).imageUrl.imageUrl != null)
            { prodLogo = products.productsList.get(i).imageUrl.imageUrl; }
        else{ prodLogo = "images/image_remove.png"; }    

        String prodLogoHeight = "";
        if(products.productsList.get(i).imageUrl != null && products.productsList.get(i).imageUrl.height != 0)
            { prodLogoHeight = Integer.toString(products.productsList.get(i).imageUrl.height); }
        else{ prodLogoHeight = Integer.toString(0); }

        String prodLogoWidth = "";
        if(products.productsList.get(i).imageUrl != null && products.productsList.get(i).imageUrl.width != 0)
            { prodLogoWidth = Integer.toString(products.productsList.get(i).imageUrl.width); }
        else{ prodLogoWidth = Integer.toString(0); }

        //Check Product Prices + Currency Attributes are Not Empty and Handle Accordingly
        String lowPriceAmount = "";
        if(products.productsList.get(i).lowestPrice != null && products.productsList.get(i).lowestPrice.amount != null)
            lowPriceAmount = products.productsList.get(i).lowestPrice.amount;

        String lowPriceCurrency = "";
        if(products.productsList.get(i).lowestPrice != null && products.productsList.get(i).lowestPrice.currency != null)
            lowPriceCurrency = products.productsList.get(i).lowestPrice.currency;

        String highPriceAmount = "";
        if(products.productsList.get(i).highestPrice != null && products.productsList.get(i).highestPrice.amount != null)
            highPriceAmount = products.productsList.get(i).highestPrice.amount;

        String highPriceCurrency = "";
        if(products.productsList.get(i).highestPrice != null && products.productsList.get(i).highestPrice.currency != null)
            highPriceCurrency = products.productsList.get(i).highestPrice.currency;           
        %>

        productResults(<%= i %>,
                        "<%= prodId %>",
                        "<%= prodName %>",
                        "<%= prodManufacturer %>",
                        "<%= prodDescription %>",
                        "<%= prodRetailer %>",
                        "<%= prodLogo %>",
                        "<%= prodLogoHeight %>",
                        "<%= prodLogoWidth %>",
                        "<%= lowPriceAmount %>",
                        "<%= lowPriceCurrency %>",
                        "<%= highPriceAmount %>",
                        "<%= highPriceCurrency %>"
                        );

        //Access Ratings from Ratings List in JSP Product Class

        <% for(int j=0; j<currProd.ratingList.size(); j++) { 

        //Check Product Rating Type is Not Empty and Handle Accordingly
        String prodRatType = "";
        if(currProd.ratingList.get(j).type != null)
            { prodRatType = currProd.ratingList.get(j).type; }
        else{ prodRatType = "no rating"; }    

        //Check Product Rating Average Value is Not Empty and Handle Accordingly
        String prodRatAvg = "";
        if(currProd.ratingList.get(j).average != null)
            { prodRatAvg = currProd.ratingList.get(j).average; }
        else{ prodRatAvg = Integer.toString(0); }

        //Check Number of Product Ratings Value is Not Empty and Handle Accordingly
        String prodRatNum = "";
        if(currProd.ratingList.get(j).numberRatings != null)
            { prodRatNum = currProd.ratingList.get(j).numberRatings; }
        else{ prodRatNum = Integer.toString(0); }

        %>

        ratingResults(<%= j %>,
                      <%= i %>,
                      "<%= prodRatType %>",
                      "<%= prodRatAvg %>",
                      "<%= prodRatNum %>"
                      );                
           <% } %>

        //Access Retailers from Retailer List in JSP Product Class

        <% for(int x=0; x<currProd.retailerList.size(); x++) {

        //Check Retiailer Logo is Not Empty and Handle Accordingly
        String retailLogo = "";
        if(currProd.retailerList.get(k).logo != null && currProd.retailerList.get(k).logo.imageUrl != null)
            retailLogo = currProd.retailerList.get(k).logo.imageUrl;

        //Check Retailer Product Prices + Currency Attributes are Not Empty and Handle Accordingly
        String minShipPrice = "";
        if(currProd.retailerList.get(k).minPriceWithShipping != null && currProd.retailerList.get(k).minPriceWithShipping.amount != null)
            minShipPrice = currProd.retailerList.get(k).minPriceWithShipping.amount;

        String minShipCurrency = "";
        if(currProd.retailerList.get(k).minPriceWithShipping != null && currProd.retailerList.get(k).minPriceWithShipping.currency != null)
            minShipCurrency = currProd.retailerList.get(k).minPriceWithShipping.currency;

        String maxShipPrice = "";
        if(currProd.retailerList.get(k).maxPriceWithShipping != null && currProd.retailerList.get(k).maxPriceWithShipping.amount != null)
            maxShipPrice = currProd.retailerList.get(k).maxPriceWithShipping.amount;

        String maxShipCurrency = "";
        if(currProd.retailerList.get(k).maxPriceWithShipping != null && currProd.retailerList.get(k).maxPriceWithShipping.currency != null)
            maxShipCurrency = currProd.retailerList.get(k).maxPriceWithShipping.currency;

        %>

        retailerResults(<%= k %>
                        <%= i %>,
                        "<%= currProd.retailerList.get(k).id %>",
                        "<%= currProd.retailerList.get(k).name %>",
                        "<%= currProd.retailerList.get(k).link %>",
                        "<%= retailLogo %>",
                        "<%= currProd.retailerList.get(k).leadTime %>",
                        "<%= currProd.retailerList.get(k).stockInfo %>",
                        "<%= currProd.retailerList.get(k).price.amount %>",
                        "<%= currProd.retailerList.get(k).price.currency %>",
                        "<%= currProd.retailerList.get(k).sourceType %>",
                        "<%= currProd.retailerList.get(k).sourceDate %>",
                        "<%= minShipPrice %>",
                        "<%= minShipCurrency%>",
                        "<%= maxShipPrice %>",
                        "<%= maxShipCurrency %>"
                        );
        <% } %>
        <% } %>
        <% } %>
        }
</script>
<script language="JavaScript" type="text/javascript">
    var mainResults = [];

    function productResults(pnum, pid, pname, pmanu, pdesc, pretail, plogo, plogoh, plogow, plowamt, plowcur, phghamt, phghcur)
    {
        var product = [];

        product.count = pnum;
        product.id = pid;
        product.name = pname;
        product.manufacturer = pmanu;
        product.description = pdesc;
        product.numretailer = pretail;
        product.logo = plogo;
        product.logoh = plogoh;
        product.logow = plogow;
        product.lowpriceamt = plowamt;
        product.lowpricecur = plowcur;
        product.highpriceamt = phghamt;
        product.highpricecur = phghcur;
        product.ratings = [];
        product.retailers = [];
        mainResults[pnum] = product;
    }

    function ratingResults(ratnum, pnum, rtgtype, rtgavg, rtgnum)
    {
        var ratings = [];

        ratings.count = ratnum;
        ratings.type = rtgtype;
        ratings.average = rtgavg;
        ratings.number = rtgnum;
        mainResults[pnum].ratings[ratnum] = ratings;
    }

    function retailerResults(retnum, pnum, rid, rname, rlink, rlogo, rtime, rstock, ramt, rcur, rstype, rsdate, rminamt, rmincur, rmaxamt, rmaxcur)
    {
        var retailers = [];

        retailers.count = retnum;
        retailers.id = rid;
        retailers.name = rname;
        retailers.purchaselink = rlink;
        retailers.logo = rlogo;
        retailers.leadtime = rtime;
        retailers.stock = rstock;
        retailers.priceamt = ramt;
        retailers.pricecur = rcur;
        retailers.sourcetype = rstype;
        retailers.sourcedate = rsdate;
        retailers.shipminprice = rminamt;
        retailers.shipmincur = rmincur;
        retailers.shipmaxprice = rmaxamt;
        retailers.shipmaxcur = rmaxcur;
        mainresults[pnum].retailers[retnum] = retailers;
    }
</script>

+1  A: 

Code generation with JSP is a baaad idea... And this is definatly the worst code generation I've ever seen. That said... lets see if we can fix your mess...

First, all those functions are meaningless, your outputting data in your jsp indiscriminatly, the functions actually only slow down performance. So we better just render the array (mainResults) you want right away.

<% if(products != null) { %>

   var mainResults = [
      <% for (int i=0; i<products.productsList.size(); i++) {
         Product currProd = products.productsList.get(i);
      %>

         {
            count : "<%= i %>",
            id : "<%= prodId %>",
            name : "<%= prodName %>",
            manufacturer : "<%= prodManufacturer %>",
            description : "<%= prodDescription %>",
            numretailer : "<%= prodRetailer %>",
            logo : "<%= prodLogo %>",
            logoh : "<%= prodLogoHeight %>",
            logow : "<%= prodLogoWidth %>",
            lowpriceamt : "<%= lowPriceAmount %>",
            lowpricecur : "<%= lowPriceCurrency %>",
            highpriceamt : "<%= highPriceAmount %>",
            highpricecur : "<%= highPriceCurrency %>",
            ratings : [
               <% for(int j=0; j<currProd.ratingList.size(); j++) { %>
                  {
                     count : "<%= j %>",
                     type : "<%= prodRatType %>",
                     average : "<%= prodRatAvg %>",
                     number : "<%= prodRatNum %>"
                  }
               <% if(j < (currProd.ratingList.size() - 1)) { %>
               ,
               <% } %>

               <% } %>
            ],
            retailers : [
               <% for(int x=0; x<currProd.retailerList.size(); x++) { %>
                  {
                     retailers.count : "<%= x %>",
                     id : "<%= currProd.retailerList.get(k).id %>",
                     name : "<%= currProd.retailerList.get(k).name %>",
                     purchaselink : "<%= currProd.retailerList.get(k).link %>",
                     logo : "<%= retailLogo %>",
                     leadtime : "<%= currProd.retailerList.get(k).leadTime %>",
                     stock : "<%= currProd.retailerList.get(k).stockInfo %>",
                     priceamt : "<%= currProd.retailerList.get(k).price.amount %>",
                     pricecur : "<%= currProd.retailerList.get(k).price.currency %>",
                     sourcetype : "<%= currProd.retailerList.get(k).sourceType %>",
                     sourcedate : "<%= currProd.retailerList.get(k).sourceDate %>",
                     shipminprice : "<%= minShipPrice %>",
                     shipmincur : "<%= minShipCurrency%>",
                     shipmaxprice : "<%= maxShipPrice %>",
                     shipmaxcur : "<%= maxShipCurrency %>"
                  }

                  <% if(x < (currProd.retailerList.size() - 1)) { %>
                  ,
                  <% } %>

               <% } %>
            ]
         }

         <% if(i < (products.productsList.size() - 1)) { %>
         ,
         <% } %>

      <% } %>
   ];

<% } %>

I might've made some typos, this was a lot of work to fix... But this is a marginally better setup.

But for the love of god, look up how to create JSON with Java and create your model in Java and then parse to JSON.

BGerrissen
Obviously... this is a pain to maintain, again, investigate and master proper use of JSON parsers in Java.
BGerrissen
Kudos for the effort :) As to converting a Java object to JSON, I'd suggest using [Google Gson](http://code.google.com/p/google-gson/). It's then as simple as `String json = new Gson().toJson(products);`.
BalusC
Thank you so so much!! Your solution works a treat and I am really grateful to you for spending your time looking at this for me :)
jimpose
I will have a serious talk with the lead developer about the use of a JSON parser but in the meantime thank you so much again for your sterling work on this for me - it is greatly aprreciated and I can finally get a good nights sleep this evening!
jimpose
In addition to thanking BGerrissen for the above solution, thank you to those who also provided their feedback on this one - what a great forum this is :)
jimpose