Extract value from JSON using ISuperObject in Delphi 10.4

877 Views Asked by At

From this JSON (excerpt from full sample):

{"sections":
  [
    {"layout_type":"media_grid"
    ,"layout_content":
      {"medias":
        [
          {"media":
            {"taken_at":1618071166
            ,"pk":2548887321653297579
            ...
            ,"user":
              {"pk":20416852171
              ,"username":"_artin.53"
              ...

My attempt to extract the value for username:

var
  json, node : ISuperObject;
  item,item2: IMember;

...
json := TSuperObject.Create(xs.Text);    // Server response
for item in json['sections'].AsArray do
begin
  for item2 in item.AsObject['medias'].AsArray  do
  begin
    u := item2.AsObject['username'].ToString;
    TThread.Synchronize (TThread.CurrentThread,
      procedure ()
      begin
        Memo1.Lines.Add(u);
      end);
  end;
end;

I get an Access Violation with this code. Using Delphi 10.4 and X-SuperObject latest version.

1

There are 1 best solutions below

3
On

Looking at the JSON data step by step and comparing it by what you did already:

  • ✓ the property sections is an array
  • ✓ each item in it is an object
  • its property layout_content is an object
  • ✓ its property medias is an array
  • ✓ each item in it is an object
  • its property media is an object
  • its property user is an object
  • ✓ its property username consists of text

Your access violation should occur when trying to access item.AsObject['medias'] which does not exist at that point, consisting of nil and as such not having any object that has a method .AsArray(). All this happens because you missed already one level, and at a later time two other levels that you also need to step thru.

You can look at what you want like a path (i.e. sections[]/layout_content/medias[]/media/user/username) whereas your code only assumes sections[]/medias[]/username.