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:
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.
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