arraysjsondelphijson-value

I want to check if there is a specific key in the json object


I want to check if the JSON object has the key "error". If it has, I want to "continue" the loop, otherwise the program can go to all the loop.

This is the JSON:

[
    {
        "cenario": {
            "origem": "",
            "out": "SNC",
            "country": "",
        },
        "item": "0015963",
        "cod": "17894904009319",
        "nat_rec": null
    },
    {
        "item": "0012868",
        "error": "product unavailable",
        "status": "unavailable",
    }
]

How can I check if the object that I'm reading has the key "error" or not?

I tried:

jValue.FindValue('error') // The problem it's going to search for all objects.
jValue.TryGetValue('error', jArray) // if it doesn't find the key in the index that it's searching at the moment, it breaks the application.

I'm doing:

response:= IdHTTP.Get(url);

jValue:= TJsonObject.ParseJSONValue(response);

for x := 0 to 2 do
begin
    
  if jValue.TryGetValue('error', jvalue) then
  begin
    continue;
  end;

  memo.Lines.Add('cod_item :' + jValue.GetValue<string>('['+intToStr(x)+'].item'));
  memo.Lines.Add('cod: ' + jValue.GetValue<string>('['+intToStr(x)+'].cod'));
end;

Solution

  • In your code, jValue is pointing at a TJSONArray, so when you call TryGetValue('error') on it, you are looking for a field named 'error' on the array itself, which obviously is not going to work. That would only work when called on a TJONObject instead.

    You would need to include each object's index when querying for the 'error' field on the array itself, eg:

    response := IdHTTP.Get(url);
    
    jValue := TJsonObject.ParseJSONValue(response);
    try
      jArray := jValue as TJSONArray;
      for x := 0 to jArray.Count-1 do
      begin
        if jArray.FindValue('['+IntToStr(x)+'].error') = nil then
          continue;
        Memo.Lines.Add('cod_item :' + jArray.GetValue<string>('['+IntToStr(x)+'].item'));
        Memo.Lines.Add('cod: ' + jArray.GetValue<string>('['+IntToStr(x)+'].cod'));
      end;
    finally
      jValue.Free;
    end;
    

    Alternatively, you can iterate the actual objects in memory instead of searching via paths, eg:

    response := IdHTTP.Get(url);
    
    jValue := TJsonObject.ParseJSONValue(response);
    try
      jArray := jValue as TJSONArray;
      for x := 0 to jArray.Count-1 do
      begin
        jObj := jArray[x] as TJSONObject;
        if jObj.GetValue('error') = nil then
        begin
          Memo.Lines.Add('cod_item :' + jObj.GetValue('item').Value);
          Memo.Lines.Add('cod: ' + jObj.GetValue('cod').Value);
        end;
      end;
    finally
      jValue.Free;
    end;