2

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 Answers 2

3

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;
Sign up to request clarification or add additional context in comments.

3 Comments

Error or-in statement cannot operate on collection type 'ISuperExpression' because 'ISuperExpression' does not contain a member for 'GetEnumerator', or it is inaccessible
Edited my answer. You should really pay more attention to variables that you use and clearly specify the question.
My Bad, i thought X-SuperObject is just an upgrade to SuperObject, Many Thanks bro
1

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.

4 Comments

for-in statement cannot operate on collection type 'ISuperExpression' because 'ISuperExpression' does not contain a member for 'GetEnumerator', or it is inaccessible , Thats why i used IMember
I wouldn't have posted my answer without having it compiled and tested before. I got no such error. Where does ISuperExpression come from? My code is exclusively iterating over ISuperObject's enumerator, which returns ISuperObjects.
Exactly at this line for section in json['sections'] do // iterate sections
Which version of SuperObject do you use? When I look at ISuperObject's declaration, there is property O[const path: SOString]: ISuperObject read GetO write PutO; default;. Thus, the return value of json['sections'] is of type ISuperObject, too. The for..in-loop requires an enumerator, which is returned from ISuperObject by its method function GetEnumerator: TSuperEnumerator;. Looking at TSuperEnumerator's declaration, there is - again - only ISuperObject returned (property Current: ISuperObject). See: github.com/hgourvest/superobject/blob/master/superobject.pas

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.