0

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
mag_sik
  • 25
  • 4
  • 2
    Use the debugger to see exactly on which line you get the access violation. You don't check if `u` is nil. Use intermediate variables before the loop and check if you get nil for the arrays. – fpiette Jun 01 '21 at 05:45
  • "Latest version" doesn't mean anything. Specify which version exactly you use and where you downloaded it. – fpiette Jun 01 '21 at 06:40
  • Do you really need TSuperobject? Delphi 10.4 offers its own libraries at http://docwiki.embarcadero.com/Libraries/Sydney/en/System.JSONss as well as http://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Json. – USauter Jul 09 '21 at 12:14

1 Answers1

3

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.

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
  • I know that already. i don't know the wat to get to it BY CODE. by your answer dose that mean i need 3 for loops ? is there a way to access `username` using code as a reference. – mag_sik Jun 01 '21 at 09:59
  • Edit your question and include what you know. If it's not in the text then it's not obvious for anyone reading it - you cannot argue "I know that already" when could have invested time and effort in writing more explanations. No, you don't need 3 loops, as you only encounter 2 arrays and it makes no sense to loop over an object when you already know which property you want to access. – AmigoJack Jun 01 '21 at 14:46
  • 1
    @mag_sik `item.AsObject['medias'].AsArray` needs to be more like `item.AsObject['layout_content'].AsObject['medias'].AsArray`, and `item2.AsObject['username'].ToString` needs to be more like `item2.AsObject['media'].AsObject['user'].AsObject['username'].ToString` – Remy Lebeau Jun 01 '21 at 18:12