Reputation: 386
I'm new to JSON parsing and I've been having trouble wrapping my head around JSONArrays and JSONObjects and how to navigate through each. My application parses JSON data and displays it in an recycler view. The JSON response contains three JSON arrays that I want to get data from. The Offices, Officials, and Address arrays. The problem here is that the address array is inside of the officials array and I don't know how to parse that data. The application works fine for some pieces of data, but when I try to parse data from the address array, I get an error from the logcat. Here is the entire JSON response
{
"normalizedInput": {
"line1": "2613 Irvington Avenue",
"city": "San Bernardino",
"state": "CA",
"zip": "92407"
},
"offices": [
{
"name": "President of the United States",
"levels": [
"country"
],
"roles": [
"headOfState",
"headOfGovernment"
]
},
{
"name": "Vice-President of the United States",
"levels": [
"country"
],
"roles": [
"deputyHeadOfGovernment"
]
},
{
"name": "United States Senate",
"levels": [
"country"
],
"roles": [
"legislatorUpperBody"
]
},
{
"name": "United States House of Representatives CA-31",
"levels": [
"country"
],
"roles": [
"legislatorLowerBody"
]
},
{
"name": "Governor",
"levels": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
]
},
{
"name": "Lieutenant Governor",
"levels": [
"administrativeArea1"
],
"roles": [
"deputyHeadOfGovernment"
]
},
{
"name": "City Treasurer"
},
{
"name": "Mayor"
},
{
"name": "City Attorney"
},
{
"name": "City Clerk"
},
{
"name": "Sheriff-Coroner"
},
{
"name": "Auditor-Controller-Treasurer-Tax Collector"
},
{
"name": "District Attorney"
},
{
"name": "Assessor-Clerk-Recorder"
},
{
"name": "San Bernardino County Superior Court Judge"
},
{
"name": "CA State Assembly District 40"
},
{
"name": "CA State Senate District 23"
},
{
"name": "Board of Supervisors, District 5"
},
{
"name": "Secretary of State"
},
{
"name": "State Treasurer"
},
{
"name": "Attorney General"
},
{
"name": "State Superintendent of Public Instruction"
},
{
"name": "State Controller"
},
{
"name": "Insurance Commissioner"
}
],
"officials": [
{
"name": "Donald J. Trump",
"address": [
{
"line1": "The White House",
"line2": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"zip": "20500"
}
],
"party": "Republican",
"phones": [
"(202) 456-1111"
],
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+whitehouse"
},
{
"type": "Facebook",
"id": "whitehouse"
},
{
"type": "Twitter",
"id": "potus"
},
{
"type": "YouTube",
"id": "whitehouse"
}
]
},
{
"name": "Mike Pence",
"address": [
{
"line1": "The White House",
"line2": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"zip": "20500"
}
],
"party": "Republican",
"phones": [
"(202) 456-1111"
],
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+whitehouse"
},
{
"type": "Facebook",
"id": "whitehouse"
},
{
"type": "Twitter",
"id": "VP"
}
]
},
{
"name": "Kamala D. Harris",
"address": [
{
"line1": "112 Hart Senate Office Building",
"city": "Washington",
"state": "DC",
"zip": "20510"
}
],
"party": "Democratic",
"phones": [
"(202) 224-3553"
],
"channels": [
{
"type": "Twitter",
"id": "KamalaHarris"
},
{
"type": "YouTube",
"id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
}
]
},
{
"name": "Dianne Feinstein",
"address": [
{
"line1": "331 Hart Senate Office Building",
"city": "Washington",
"state": "DC",
"zip": "20510"
}
],
"party": "Democratic",
"phones": [
"(202) 224-3841"
],
"photoUrl": "http://bioguide.congress.gov/bioguide/photo/F/F000062.jpg",
"channels": [
{
"type": "Facebook",
"id": "SenatorFeinstein"
},
{
"type": "Twitter",
"id": "SenFeinstein"
},
{
"type": "YouTube",
"id": "SenatorFeinstein"
}
]
},
{
"name": "Pete Aguilar",
"address": [
{
"line1": "1223 Longworth House Office Building",
"city": "Washington",
"state": "DC",
"zip": "20515"
}
],
"party": "Democratic",
"phones": [
"(202) 225-3201"
],
"photoUrl": "https://aguilar.house.gov/sites/aguilar.house.gov/files/styles/congress_image_medium/public/wysiwyg_uploaded/Headshot_0.jpg?itok=LSt7qkOV",
"channels": [
{
"type": "Facebook",
"id": "reppeteaguilar"
},
{
"type": "Twitter",
"id": "RepPeteAguilar"
},
{
"type": "YouTube",
"id": "UCIXCmfuRWrbgdTw257_lxJQ"
},
{
"type": "YouTube",
"id": "UCxwbFLOlKDsXrwizV5jah7g"
}
]
},
{
"name": "Edmund G. Brown Jr.",
"address": [
{
"line1": "c/o State Capitol",
"line2": "Suite 1173",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-2841"
],
"channels": [
{
"type": "GooglePlus",
"id": "+JerryBrown"
},
{
"type": "Facebook",
"id": "jerrybrown"
},
{
"type": "Twitter",
"id": "JerryBrownGov"
}
]
},
{
"name": "Gavin Newsom",
"address": [
{
"line1": "State Capitol",
"line2": "Suite 1114",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-8994"
],
"photoUrl": "http://www.ltg.ca.gov/images/newsimages/i2.png",
"emails": [
"[email protected]"
],
"channels": [
{
"type": "GooglePlus",
"id": "+GavinNewsom"
},
{
"type": "Facebook",
"id": "GavinNewsom"
},
{
"type": "Twitter",
"id": "gavinnewsom"
}
]
},
{
"name": "David C. Kennedy",
"address": [
{
"line1": "300 N. \"D\" Street",
"line2": "2nd Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5022"
]
},
{
"name": "R. Carey Davis",
"address": [
{
"line1": "300 N. \"D\" Street - 6th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5133"
],
"channels": [
{
"type": "Facebook",
"id": "MayorCareyDavis"
}
]
},
{
"name": "Gary D. Saenz",
"address": [
{
"line1": "300 N. \"D\" Street",
"line2": "6th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5355"
],
"emails": [
"[email protected]"
]
},
{
"name": "Georgeann \"Gigi\" Hanna",
"address": [
{
"line1": "300 N. \"D\" Street",
"line2": "2nd Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5002"
]
},
{
"name": "John McMahon",
"address": [
{
"line1": "655 East Third Street",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(760) 956-5001"
],
"emails": [
"[email protected]"
],
"channels": [
{
"type": "Facebook",
"id": "sbcountysheriff"
},
{
"type": "Twitter",
"id": "sbcountysheriff"
}
]
},
{
"name": "Oscar Valdez",
"address": [
{
"line1": "222 W. Hospitality Lane",
"line2": "4th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 382-7014"
]
},
{
"name": "Michael Ramos",
"address": [
{
"line1": "303 West 3rd Street",
"line2": "6th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 382-3669"
],
"channels": [
{
"type": "Facebook",
"id": "SanBernardinoCountyDistrictAttorney"
},
{
"type": "Twitter",
"id": "sbcountyda"
}
]
},
{
"name": "Bob Dutton",
"address": [
{
"line1": "First Floor",
"line2": "222 W. Hospitality Lane",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(855) 732-2575"
]
},
{
"name": "Denise Trager Dvorak",
"party": "Nonpartisan"
},
{
"name": "James C. Ramos",
"address": [
{
"line1": "PO BOX 942849",
"city": "Sacramento",
"state": "CA",
"zip": "94249"
}
],
"party": "Democratic Party",
"phones": [
"(916) 319-2040"
]
},
{
"name": "Mike Morrell",
"address": [
{
"line1": "STATE CAPITOL",
"line2": "1303 10TH ST RM 3056",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Republican",
"phones": [
"(909) 919-7731"
],
"photoUrl": "http://senate.ca.gov/sites/senate.ca.gov/files/senator_photos/morrell-mike.jpg",
"emails": [
"[email protected]"
],
"channels": [
{
"type": "Twitter",
"id": "MikeMorrellGOP"
},
{
"type": "Facebook",
"id": "MikeMorrellGOP"
}
]
},
{
"name": "Josie Gonzales",
"address": [
{
"line1": "385 N. Arrowhead Ave.",
"line2": "5th Fl.",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 387-4565"
],
"channels": [
{
"type": "Facebook",
"id": "supervisorgonzales"
},
{
"type": "Twitter",
"id": "SupervisorJosie"
}
]
},
{
"name": "Alex Padilla",
"address": [
{
"line1": "1500 11th Street,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 653-7244"
],
"emails": [
"[email protected]"
],
"channels": [
{
"type": "Facebook",
"id": "CaliforniaSOS"
},
{
"type": "Twitter",
"id": "CASOSvote"
}
]
},
{
"name": "John Chiang",
"address": [
{
"line1": "P.O. Box 942809",
"city": "Sacramento",
"state": "CA",
"zip": "94209"
}
],
"party": "Democratic",
"phones": [
"(916) 653-2995"
],
"channels": [
{
"type": "Twitter",
"id": "STONewsroom"
}
]
},
{
"name": "Xavier Becerra",
"address": [
{
"line1": "Office of the Attorney General",
"line2": "1300 \"I\" Street",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-9555"
],
"channels": [
{
"type": "Facebook",
"id": "XavierBecerra"
},
{
"type": "Twitter",
"id": "AGBecerra"
}
]
},
{
"name": "Tom Torlakson",
"address": [
{
"line1": "1430 N Street,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Nonpartisan",
"phones": [
"(916) 319-0800"
],
"emails": [
"[email protected]"
],
"channels": [
{
"type": "Facebook",
"id": "CAEducation"
},
{
"type": "Twitter",
"id": "cadepted"
}
]
},
{
"name": "Betty T. Yee",
"address": [
{
"line1": "P.O. Box 942850",
"city": "Sacramento",
"state": "CA",
"zip": "94250"
}
],
"party": "Democratic",
"phones": [
"(916) 445-2636"
],
"channels": [
{
"type": "Facebook",
"id": "137732083043662"
},
{
"type": "Twitter",
"id": "CAController"
}
]
},
{
"name": "Dave Jones",
"address": [
{
"line1": "300 Capitol Mall,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 492-3500"
],
"channels": [
{
"type": "GooglePlus",
"id": "108233445289196913395"
},
{
"type": "Facebook",
"id": "insurancecagov"
},
{
"type": "Twitter",
"id": "CDINews"
}
]
}
]
}
Parse function:
//fetch json data from Civic API
private void getData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressDialog.dismiss();
try{
JSONObject jsonObject = new JSONObject(response);
//first loop through offices array. Retrieve officeName value
JSONArray officesArray = jsonObject.getJSONArray("offices"); //One array for offices
JSONArray officialsArray = jsonObject.getJSONArray("officials"); //one array for officials
for (int i = 0; i < officesArray.length(); i++) {
JSONObject jsonOffices = officesArray.getJSONObject(i);
JSONObject jsonOfficials = officialsArray.getJSONObject(i);
JSONObject jsonAddress = jsonOfficials.getJSONObject("address");
String line1 = jsonAddress.getJSONObject("address").getString("line1");
String city = jsonAddress.getJSONObject("address").getString("city");
String state = jsonAddress.getJSONObject("address").getString("state");
String zip = jsonAddress.getJSONObject("address").getString("zip");
if (jsonOfficials.has("photoUrl")) {
Reps reps1 = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"),
jsonOfficials.getString("photoUrl"),
line1,
city,
state,
zip
);
repList.add(reps1);
} else {
Reps reps2 = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"),
line1,
city,
state,
zip
);
repList.add(reps2);
}
}
adapter = new RepRvAdapter(repList, getApplicationContext());
myrv.setAdapter(adapter);
}catch (JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
The logcat error says that the JSONArray cannot be converted to JSONObject
I understand why I am getting this error. It is because I am calling .getJSONObject on a JSON Array, but I'm not sure how to go about fixing it.
EDIT: Added some log tags for troubleshooting. Looks like no value for address is found for Denise Trager Dvorak. This is where the error is. How do I fix it?
Upvotes: 0
Views: 163
Reputation: 337
As you said address
is a JSONArray which contains an object with the address information.
So you need to access the first object in the array and get the information from there like this:
//fetch json data from Civic API
private void getData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressDialog.dismiss();
try{
JSONObject jsonObject = new JSONObject(response);
//first loop through offices array. Retrieve officeName value
JSONArray officesArray = jsonObject.getJSONArray("offices"); //One array for offices
JSONArray officialsArray = jsonObject.getJSONArray("officials"); //one array for officials
for (int i = 0; i < officesArray.length(); i++) {
JSONObject jsonOffices = officesArray.getJSONObject(i);
JSONObject jsonOfficials = officialsArray.getJSONObject(i);
JSONArray jsonAddress = jsonOfficials.getJSONArray("address");
String line1 = jsonAddress.getJSONObject(0).getString("line1");
String city = jsonAddress.getJSONObject(0).getString("city");
String state = jsonAddress.getJSONObject(0).getString("state");
String zip = jsonAddress.getJSONObject(0).getString("zip");
if (jsonOfficials.has("photoUrl")) {
Reps reps1 = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"),
jsonOfficials.getString("photoUrl"),
line1,
city,
state,
zip
);
repList.add(reps1);
} else {
Reps reps2 = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"),
line1,
city,
state,
zip
);
repList.add(reps2);
}
}
adapter = new RepRvAdapter(repList, getApplicationContext());
myrv.setAdapter(adapter);
}catch (JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
EDIT1:
I have adapted the code to try it locally on my machine with your provided json and everything is working find. Here you can see the images:
Could you please log some results in the solution I posted earlier and check if maybe some object don't have an address, or maybe we are missing something else.
Upvotes: 1