Mahdi Parsa Mahdi Parsa - 4 months ago 58
JSON Question

lazarus - TJSONData path exists

I am trying to work with JSON, but my problem is that I can't find any method for checking if a path exists or get a path list.

For example, my app receives this JSON from a server:

{
"ok": true,
"result":[
{
"id": 12,
"first_name": "David",
"username": "Fake"
},
{
"id": 13,
"first_name": "John",
"username": "sample",
"message":"test msg"
}
,{
"id": 13,
"first_name": "David",
"username": "Fake",
"text":"test txet"
}
]

}


But the data is not equal, for example
John
has a
message
but
David
does not.

Note: If I try to read
message
for everybody, I get an exception in the code.

Here is my code:

for i := 0 to jsonDoc.findpath('result').Count - 1 do
begin
// jsonDoc.findpath('result').Items[i].WHAT IS NEED FOR CHECK ??

Result[i].text := jsonDoc.findpath('result').Items[i].FindPath('message').AsString; // exception
end;


Please guide me to find a path list or check if a path exists.

Answer

First, your use of findPath('result') is grossly inefficient. You should be calling it one time and saving the returned object to a local variable.

Second, FindPath() returns nil if the specified path is not found, but you are not checking for that condition, which is why you are getting an exception when message is missing.

Try this instead:

var
  jsonDoc, r: TJSONData;
  msg: TJSONData;
  I: Integer;
begin
  jsonDoc := ...;
  r := jsonDoc.findpath('result');
  if r <> nil then
  begin
    for i := 0 to res.Count - 1 do
    begin
      msg := res.Items[i].FindPath('message');
      if msg <> nil then
        Result[i].text := msg.AsString
      else
        Result[i].text := '';
    end;
  end;
end;

Please read Lazarus' documentation for more details:

Reference for unit 'fpjson'

Comments