I am making my first steps with JSON and I am looking for a solution to get the number of items in a TJSONArray
. I need the number to count up in a For
Loop.
The following code is working for me, just the count up which is now set to 5 should be replaced by number of items in the array. I already tried JsonArray.Count-1
, which according to my research should be the right way, but just replacing the number by JsonArray.Count-1
results in an Access Violation.
var
JSonObject: TJSonObject;
JSonValue: TJSonValue;
JSOnArray: TJsonArray;
st: string;
id, name, description, sku, price: string;
i, j: integer;
begin
st := Memo1.Text;
j := 1;
if Assigned(JSONArray) then
begin
For i := 0 to 5 -1 do
Begin
JSonObject := TJSonObject.Create;
JsonValue:=JSonObject.ParseJSONValue(st);
if (JSONValue is TJSONArray) then
Begin
id := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('id').JSONValue.Value;
sku := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('sku').JSONValue.Value;
description := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('description').JSONValue.Value;
name := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('name').JSONValue.Value;
price := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('price').JSONValue.Value;
stringgrid1.Cells[1,j] := sku;
stringgrid1.Cells[2,j] := name;
stringgrid1.Cells[4,j] := description;
stringgrid1.Cells[3,j] := price;
j:=j+1;
End;
End;
JSonObject.Free;
end;
JsonArray.Count
is the correct value to use. However, the Access Violation is because JsonArray
is still unassigned at the point where you try to evaluate the for
loop.
The way you have written your code, your for
loop is re-parsing the same JSON over and over 1, accessing a different array element each time. That is why things seemingly work when you hard-code the count.
TJsonObject
you create except the last one, and also leaking every TJsonValue
that ParseJsonValue()
returns.The fix is to parse the JSON before you run the loop. Don't parse the JSON inside of the loop.
Also, you do not need to create a TJSONObject
instance to call ParseJSONValue()
, as it is a class static
method. You can call it directly on the TJSONObject
class itself.
Try something more like this:
var
JSonObject: TJSonObject;
JSonValue: TJSonValue;
JSonArray: TJsonArray;
id, name, description, sku, price: string;
i, j: integer;
begin
JsonValue := TJSONObject.ParseJSONValue(Memo1.Text);
if Assigned(JsonValue) then
try
JSonArray := JsonValue as TJSONArray;
j := 1;
for i := 0 to JSonArray.Count-1 do
begin
JSonObject := JSonArray.Items[i] as TJSonObject;
id := JSonObject.GetValue('id').Value;
sku := JSonObject.GetValue('sku').Value;
description := JSonObject.GetValue('description').Value;
name := JSonObject.GetValue('name').Value;
price := JSonObject.GetValue('price').Value;
StringGrid1.Cells[1,j] := sku;
StringGrid1.Cells[2,j] := name;
StringGrid1.Cells[3,j] := price;
StringGrid1.Cells[4,j] := description;
Inc(j);
end;
finally
JsonValue.Free;
end;
end;