I'm working on a project where the API returns a JSON response with nested Array Objects. I've tried to loop through to get the inner most array of string (Hex) items. But the item shows as null.
Here is the JSON response: I'm trying to access the main part below, which is an array of string hex bytes.
{ // The main response
"Success": true,
"Total": 49,
"TotalPages": 49,
"ModesList": [
{
"Id": 1058,
"Name": "kharabeesh",
"Order": 0,
"StepOneTime": "2.03s",
"UserId": 1015,
"IsPublic": true,
"User": "Sahar M",
"Date": "02/06/2021",
"Mode": [ // I'm trying to access this part
[
"16",
"1",
"1",
"0",
"5",
"71",
"255",
"255",
"255",
"76",
"20"
],
[
"16",
"2",
"1",
"6",
"53",
"71",
"76",
"3",
"33",
"0",
"17"
],
[
"16",
"3",
"1",
"6",
"53",
"71",
"73",
"127",
"87",
"0",
"17"
],
[
"16",
"4",
"1",
"7",
"181",
"127",
"127",
"119",
"45",
"0",
"17"
],
[
"16",
"5",
"1",
"0",
"7",
"192",
"170",
"48",
"11",
"0",
"32"
],
[
"16",
"6",
"1",
"7",
"130",
"15",
"67",
"71",
"170",
"0",
"32"
],
[
"16",
"7",
"1",
"0",
"67",
"8",
"206",
"45",
"195",
"0",
"68"
]
]
}
]
}
Here is what I have so far:
public class GetModesResponse
{
public bool Success;
public long Total;
public long TotalPages;
public List<ModesList>[] ModesList;
}
public class ModesList
{
public long Id;
public string Name;
public long Order;
public string StepOneTime;
public long UserId;
public bool IsPublic;
public string User;
public string Date;
public List<long>[] Mode;
}
private void PopulateModes(GetModesResponse publicModes)
{
var allModes = publicModes.ModesList;
var index = 0;
foreach(var mode in allModes[0])
{
Debug.Log(mode.Name);
var modeItem = Instantiate(ModeItemPrefab, ModeContainer.transform);
var usedColors = new List<Color>();
var steps = mode.Mode[0];
Debug.Log(steps[0]);
var stepColor = mainScript.GetColor((byte) steps[6], (byte) steps[7], (byte) steps[8], (byte) steps[9], 0);
if (!usedColors.Contains(stepColor))
{
usedColors.Add(stepColor);
}
modeItem.Initialize(index, (int) mode.Id, mode.Name, mode.User, usedColors, this);
}
}
Update
This is how I call the populate function after getting the JSON from the API:
private IEnumerator GetPublicModes()
{
WWWForm form = new WWWForm();
form.AddField("keyword", "");
form.AddField("size", 1000);
form.AddField("pageNo", 1);
using (UnityWebRequest www = UnityWebRequest.Post(Manager.ApiUrlBase + "GetModes", form))
{
yield return www.SendWebRequest();
if (!www.isDone)
{
Debug.Log(www.error);
}
else
{
var response = www.downloadHandler.text;
Debug.Log("Get Modes complete!");
GetModesResponse getModesResponse = new GetModesResponse();
getModesResponse = JsonUtility.FromJson<GetModesResponse>(response);
Debug.Log(getModesResponse.ToString());
if (getModesResponse.Success)
{
//Populate List
gottenModes = getModesResponse;
PopulateModes(getModesResponse);
}
else
{
// Display Error Message
Debug.Log(response);
}
}
}
}
UPDATE Solution: Thank you @MajidMohammadi, @AttilaMolnar, @A_____, and @derHugo for your help. @derHugo helped me find the answer by going to https://json2csharp.com/ it finally worked. Here is how I did it in the end:
[Serializable]
public class ModesList
{
public ModesList(
int id,
string name,
int order,
string stepOneTime,
int userId,
bool isPublic,
string user,
string date,
List<List<string>> mode
)
{
this.Id = id;
this.Name = name;
this.Order = order;
this.StepOneTime = stepOneTime;
this.UserId = userId;
this.IsPublic = isPublic;
this.User = user;
this.Date = date;
this.Mode = mode;
}
public int Id;
public string Name;
public int Order;
public string StepOneTime;
public int UserId;
public bool IsPublic;
public string User;
public string Date;
public List<List<string>> Mode;
}
[Serializable]
public class GetModesResponse
{
public GetModesResponse(
bool success,
int total,
int totalPages,
List<ModesList> modesList
)
{
this.Success = success;
this.Total = total;
this.TotalPages = totalPages;
this.ModesList = modesList;
}
public bool Success;
public int Total;
public int TotalPages;
public List<ModesList> ModesList;
}
NullReferenceException: Object reference not set to an instance of an object GalleryPanelScript.PopulateModes (GalleryPanelScript+GetModesResponse publicModes) (at Assets/Scripts/GalleryPanelScript.cs:83)which is this part of the code:foreach(var mode in allModes[0])public List<ModesList>[] ModesList;should only bepublic List<ModesList> ModesList;, as ModeList is just a simple list not a nested list. And when you specified this in the other modelpublic List<long>[] Mode;I am not sure it can be true because numbers are in apostrophes ("), so from JSON syntax view they must be string not long (unless if you do not have any conversion function for that record). I would specify it on this way:public List<List<string>> Mode;