Wasim Abuzaher Wasim Abuzaher - 7 months ago 11
Java Question

Aggregate results from multiple HTTP requests to a single list

I am parsing several Json links, and trying to add all output to one

List
. However the list always gets overwritten instead to only include the results from one of the links:

public class GetShopifyJsonData extends GetRawData {
private String LOG_TAG = GetShopifyJsonData.class.getSimpleName();
private List<Product> mProduct;
private Uri mDestination;

public GetShopifyJsonData(int page) {
super(null);
createUri(page);
mProduct = new ArrayList<Product>();
}

public void execute(){
super.setRawUrl(mDestination.toString());
DownloadShopifyData downloadShopifyData = new DownloadShopifyData();
Log.v(LOG_TAG, "Built URI = " + mDestination.toString());
downloadShopifyData.execute(mDestination.toString());
}

public boolean createUri(int page) {
final String SHOPIFY_BASE_URL = "";
final String SHOPIFY_PAGE_PARAM = "page";

mDestination = Uri.parse(SHOPIFY_BASE_URL).buildUpon()
.appendQueryParameter(SHOPIFY_PAGE_PARAM, String.valueOf(page)).build();

return mDestination != null;
}

public void processResults() {

if(getDownloadStatus() != DownloadStatus.OK){
Log.e(LOG_TAG, "Error Downloading Raw Data");
return;
}

final String SH_PRODUCTS = "products";
final String SH_TYPE = "product_type";
final String SH_VARIANTS = "variants";
final String SH_TITLE = "title";
final String SH_PRICE = "price";
final String SH_GRAMS = "grams";

try {
JSONObject jsonData = new JSONObject(getData());
JSONArray productsArray = jsonData.getJSONArray(SH_PRODUCTS);
for (int i=0; i<productsArray.length(); i++ ) {
JSONObject jsonProduct = productsArray.getJSONObject(i);
String productType =jsonProduct.getString(SH_TYPE);
String title = jsonProduct.getString(SH_TITLE);

JSONArray variantsArray = jsonProduct.getJSONArray(SH_VARIANTS);
JSONObject variantProduct = variantsArray.getJSONObject(0);
String variantTitle = variantProduct.getString(SH_TITLE);
double price = variantProduct.getDouble(SH_PRICE);
int grams = variantProduct.getInt(SH_GRAMS);

if (productType.equals("Keyboard") || productType.equals("Computer")) {
Product productObject = new Product(title, price, grams, productType, variantTitle);
this.mProduct.add(productObject);
}
}

for(Product singleProduct : mProduct){
Log.v(LOG_TAG, singleProduct.toString());
Log.v(LOG_TAG, String.valueOf(mProduct.size()));
}
} catch (JSONException jsone) {

jsone.printStackTrace();
Log.e(LOG_TAG, "Error Processing JSON data");
}
}
}


And the call from
MainActivity
:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

for (int i=1; i<6; i++) {
GetShopifyJsonData jsonData = new GetShopifyJsonData(i);
jsonData.execute();
}
}


What do I need to change to get the products to add to each other in a single list?

Answer

Each GetShopifyJsonData has its own List<Product> and you need to aggregate those by either having a single GetShopifyJsonData instance request all the products or by having your MainActivity aggregate them as the requests complete. This approach implements the latter.

Add a callback interface to GetShopifyJsonData and require an instance of it as a parameter in the constructor. I only included the changes in the code below. Everything else is the same.

public class GetShopifyJsonData extends GetRawData {
    public interface OnResultsReadyListener {
        void onResultsReady(List<Product> products);
    }

    private OnResultsReadyListener mResultsListener;

    public GetShopifyJsonData(int page, OnResultsReadyListener resultsListener) {
        super(null);
        createUri(page);
        mProduct = new ArrayList<Product>();
        mResultsListener = resultsListener;
    }

    public void processResults() {
        // Add this to the end of the method
        if(mResultsListener != null) {
            mResultsListener.onResultsReady(mProduct);
        }
    }
}

And then update MainActivity to implement this new interface and add results to its list as requests complete.

public class MainActivity extends Activity
        implements GetShopifyJsonData.OnResultsReadyListener {
    private List<Product> allproducts;

    @Override
    void onResultsReady(List<Product> products) {
        // allProducts contains products for all requests that have completed so far
        allProducts.addAll(products);
        Log.v(LOG_TAG, allProducts.size() + " total products downloaded.");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        allProducts = new ArrayList<>();

        for (int i=1; i<6; i++) {
            GetShopifyJsonData jsonData = new GetShopifyJsonData(i, this);
            jsonData.execute();
        }
    }
}