How to access nested values in JSON using X-SuperObject

2.1k Views Asked by At

I want to get all the users from this json.

{
  "status": "ok",
  "next_max_id": "AQAmA1l9NAQXa",
  "sections": [
    {
      "module": null,
      "show_view_all": null,
      "title": null,
      "users": [
        {
          "pk": 48165888,
          "is_verified": false,
          "profile_pic_url": "http://scontent-sit4-1.cdninstagram.com/t51.2885-19/s150x150/17332306_1915592632007479a.jpg",
          "full_name": "Jason Giovany Castro Morales",
          "is_private": false,
          "has_anonymous_profile_picture": false,
          "username": "jasongiovanycastromorales",
          "profile_pic_id": "14699765111792881_48165888"
        }
      ]
    }
  ]
}

Now, my attempt to get all usernames.

procedure TForm2.Button6Click(Sender: TObject);
var
  json : ISuperObject;
  node : ISuperObject;
  item : IMember;
begin
  try
    json := TSuperObject.Create(list.Text);

    for item in json['sections.users'].AsArray do
    begin
      node := item.AsObject;
      Memo4.Lines.Add(node.S['username']);
    end;
  finally
  end;
end;

2nd attempt.. i get an AV !

var
    json         : ISuperObject;
    node         : ISuperObject;
    item, item2         : IMember;
  begin
     json := SO(list.Text);

   for item in json['sections'].AsArray do
    begin
       for item2 in json['users'].AsArray do
        begin
        node := item.AsObject;

        Memo1.Lines.Add(node.S['username']);
       end;
     end;
  end;

there are 200 username value in this JSON I get nothing, sometimes AV when i try to play around withthe json code, my question is, how to parse this json correctly to get the value username? Thank You.

2

There are 2 best solutions below

3
On BEST ANSWER

Your example is broken and you didn't specify the format of input data, like I don't know, if all objects in sections array contains users array. Anyway, this example should be working for your snippet.

SuperObject

procedure TForm2.Button6Click(Sender: TObject);
var
  json, user, section : ISuperObject;
begin
  json := SO(list.Text);
  for section in json['sections'] do
  begin
    if Assigned(section['users']) then
    begin
      for user in section['users'] do
      begin
        if user.S['username'] <> '' then
          Memo4.Lines.Add(user.S['username']);
      end;
    end;
  end;
end;

EDIT : In fact, you are not using SuperObject, but X-SuperObject, which is something different. Even though I've never used that library, I was able to find the problem only with examples from their website, because u make simple mistakes like using item instead of item2 or json and item in second loop.

X-SuperObject

procedure TForm2.Button6Click(Sender: TObject);
var
  json : ISuperObject;
  item, item2 : IMember;
begin
  json := TSuperObject.Create(list.Text);
  for item in json['sections'].AsArray do
  begin
    for item2 in item.AsObject['users'].AsArray do
      Memo1.Lines.Add(item2.AsObject['username'].ToString);
  end;
end;
4
On

DISCLAIMER: this answer relates to SuperObject. At the time, this answer was given, it was unknown that the question actually refers to XSuperObject.


I get nothing

This is unlikely because you should at least get an access violation. This is because, you are not creating the superobject the right way.

I recommend you to use the factory function SO() instead of calling the constructor TSuperObject.Create.

Then you have to remember that both sections and users are arrays. Thus, you need to iterate both arrays in a nested iteration:

var
  json: ISuperObject;
  section: ISuperObject;
  user: ISuperObject;
begin
  json := SO(list.Text);
  for section in json['sections'] do // iterate sections
    for user in section['users'] do  // iterate users
      Memo4.Lines.Add(user.S['username']);
 end;

Note: This example is a minimal approach. You should add further checking (e.g. Assigned()) to prevent exceptions.