4

For a college assignment I need to create an app that retrieves product data from the API of a well known Dutch online store. I need to store the title, summary, price and image URLs of each product into a new Product object. These Products are stored into an ArrayList and the ArrayList is then returned.

Each product within the products array has a nested array called "images", which contains 6 product images. These images need to stored into my Product object's HashMap attribute, with the image size as key and the URL as value. However, I can't seem to get it right.

JSON data with the query "pokemon": https://api.bol.com/catalog/v4/search/?apikey=25C4742A92BF468EB2BD888FC8FBFF40&format=json&q=pokemon

Product class:

package com.example.bolcombrowser.domain;

import java.util.Map;

public class Product {

    // Attributes
    private String mTitle;
    private String mSummary;
    private double mPrice;
    private Map < String, String > mImageUrls;

    // Constructor
    public Product(String mTitle, String mSummary, double mPrice, Map < String, String > mImageUrls) {
        this.mTitle = mTitle;
        this.mSummary = mSummary;
        this.mPrice = mPrice;
        this.mImageUrls = mImageUrls;
    }

    // Getters and Setters
    public String getmTitle() {
        return mTitle;
    }

    public void setmTitle(String mTitle) {
        this.mTitle = mTitle;
    }

    public String getmSummary() {
        return mSummary;
    }

    public void setmSummary(String mSummary) {
        this.mSummary = mSummary;
    }

    public double getmPrice() {
        return mPrice;
    }

    public void setmPrice(double mPrice) {
        this.mPrice = mPrice;
    }

    public Map < String, String > getImageUrls() {
        return mImageUrls;
    }

    public void setImageUrls(Map < String, String > imageUrls) {
        this.mImageUrls = imageUrls;
    }
}

parseJson method:

public static ArrayList < Product > parseJson(String productJsonStr) throws JSONException {

    /* JSON array names. */
    final String BOL_PRODUCTS = "products";
    final String BOL_IMAGES = "images";
    final String BOL_OFFERS = "offers";

    /* JSON key names. */
    final String BOL_TITLE = "title";
    final String BOL_SUMMARY = "summary";
    final String BOL_OFFERDATA = "offerData";
    final String BOL_PRICE = "price";
    final String BOL_KEY = "key";
    final String BOL_URL = "url";

    /* Variables to store product data into, and is then used to create new Product objects. */
    String title;
    String summary;
    double price;
    Map < String, String > imageUrls = new HashMap < > ();

    /* ArrayList to store products into. */
    ArrayList < Product > productList = new ArrayList < > ();

    JSONObject productsJson = new JSONObject(productJsonStr);

    JSONArray productsArray = productsJson.getJSONArray(BOL_PRODUCTS);

    for (int i = 0; i < productsArray.length(); i++) {
        JSONObject product = productsArray.getJSONObject(i);

        /* Retrieve the title and summary of each product. */
        title = product.getString(BOL_TITLE);
        summary = product.getString(BOL_SUMMARY);

        JSONArray imagesArray = product.getJSONArray(BOL_IMAGES);

        for (int j = 0; j < imagesArray.length(); j++) {
            JSONObject image = imagesArray.getJSONObject(j);

            /* Retrieve each product's image sizes and URLs and store them into a HashMap. */
            String imageSize = image.getString(BOL_KEY);
            String imageUrl = image.getString(BOL_URL);

            imageUrls.put(imageSize, imageUrl);
        }

        JSONObject offerData = product.getJSONObject(BOL_OFFERDATA);
        JSONArray offers = offerData.getJSONArray(BOL_OFFERS);
        JSONObject offer = offers.getJSONObject(0);
        price = offer.getDouble(BOL_PRICE);

        productList.add(new Product(title, summary, price, imageUrls));
    }

    return productList;
}

onPostExecute method:

@Override
protected void onPostExecute(String productData) {
    if (productData != null) {
        ArrayList < Product > productList;

        try {
            productList = JsonUtils.parseJson(productData);

            for (Product product: productList) {
                String title = product.getmTitle();
                String summary = product.getmSummary();
                double price = product.getmPrice();
                String hashMap = product.getImageUrls().toString();

                mTextViewOutput.append(title + "\n\n" + summary + "\n\n" + price + "\n\n" +
                    hashMap + "\n\n\n\n\n");
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

When I test out my app, it seems to have stored the image URLs of the last product into every product's HashMap:

enter image description here

I've been staring at my code for hours and I can't seem to find out why it does this. I'm probably making a very silly mistake but I just can't seem to figure out what it is exactly.

1 Answer 1

3

Your Map<String, String> imageUrls = new HashMap<>(); is in the wrong place. It should be inside your first for loop, otherwise you are using the same Map for all your products.

...
for (int i = 0; i < productsArray.length(); i++) {
    Map<String, String> imageUrls = new HashMap<>();
...

By the way, I suggest using gson library. It will make your code less boilerplate

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! That fixed it. I will definitely look into gson.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.