1

I'm trying to parse a JSON file using ISuperObject. My JSON file looks like this:

{
   "status":"ok",
   "follows":{
      "count":868,
      "page_info":{
         "has_previous_page":false,
         "start_cursor":null,
         "end_cursor":"SbXc6VJsoeTs",
         "has_next_page":true
      },
      "nodes":[
         {
            "username":"username1",
            "requested_by_viewer":false,
            "followed_by_viewer":true,
            "profile_pic_url":"URL link",
            "full_name":"name",
            "is_verified":false,
            "id":"ID"
         },
         {
            "username":"username2",
            "requested_by_viewer":false,
            "followed_by_viewer":true,
            "profile_pic_url":"URL link",
            "full_name":"username2",
            "is_verified":false,
            "id":"ID"
         },
         {
            "username":"_username3",
            "..."
         ]
      }

I want all of the username values to be listed in a Memo.

Here is what I have tried:

var
 json         : ISuperObject;
 row_item     : ISuperObject;
begin
  json := TSuperObject.ParseFile('C:\json.txt', TRUE); 
  for row_item in json['nodes'] do 
  begin
    Memo1.Lines.Add(elements_itemS['usernames']); 
  end;
end;

I get an Access Violation on the for loop. Any ideas?

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
ColdZer0
  • 233
  • 1
  • 4
  • 19
  • `for username in json['nodes'] do through elements array` is not valid Delphi code, which means it's not what you have tried. If you want help with your code, **post your code**. It seems to me we've had this discussion before... – Ken White Jun 28 '16 at 01:58
  • i used this answer [http://stackoverflow.com/questions/19415616/how-to-parse-specified-value-from-json-object-in-delphi-xe3], maybe. @KenWhite – ColdZer0 Jun 28 '16 at 02:09
  • The code you linked does not use ISuperObject, and it's not anything like the code you've posted here. I repeat: If you want help with your code, **post YOUR CODE**. Not something else, not a link to something unrelated, not something you made up while writing your question here - the **actual code** that you **copy and paste** from the IDE's code editor, that will actually compile. – Ken White Jun 28 '16 at 02:12
  • i used the second answer from that post, with some changes,however, the code compiles successfully. updated. @KenWhite – ColdZer0 Jun 28 '16 at 02:18
  • @KenWhite: `for row_item in json['nodes']` is valid Delphi code. It is a [container iteration loop](http://docwiki.embarcadero.com/RADStudio/en/Declarations_and_Statements_(Delphi)#Iteration_Over_Containers_Using_For_statements) using an Enumerator, and `ISuperObject` implements a Delphi-compatible Enumerator for JSON nodes. However, the `elements_itemS` looks suspicious wrong. – Remy Lebeau Jun 28 '16 at 02:23
  • @Remy: Can you point me to the documentation where it says *for in do through elements array** is acceptable to the compiler? It's not valid code - valid code *compiles*. I'm fully aware of the correct syntax to use for `for..in`, and that isn't it. The poster should include **valid code**. – Ken White Jun 28 '16 at 02:26
  • @KenWhite: `for..in` is documented on the link I posted in my last comment. Or, are you referring to the `through elements array*` portion? – Remy Lebeau Jun 28 '16 at 02:28
  • @Remy: That link does not say what you indicate it does. There's no `do through elements array` anywhere in that syntax or the examples. I'm referring to the poster including something indicated as what has **been tried** when clearly that's not it, because what was posted will not compile, and then the link received in reply was to something totally not related to ISuperObject (it uses TJSONObject instead, and doesn't even look vaguely like what's posted here.) – Ken White Jun 28 '16 at 02:30
  • @KenWhite: there is no `elements_itemS` in `ISuperObject`, so where are you getting `elements array*` from? – Remy Lebeau Jun 28 '16 at 02:32
  • @Remy: From the post before it was just edited. Look at the initial post (revision 1), which is when I asked for the actual code. – Ken White Jun 28 '16 at 02:32
  • 2
    Pretty disappointing that you post invalid JSON and code that does not compile. Your real problem is a lack of attention to detail. You need to learn the discipline of how to prepare a [mcve]. – David Heffernan Jun 28 '16 at 08:47
  • well, this is first time dealing with JSON, however, updated @DavidHeffernan – ColdZer0 Jun 28 '16 at 15:23

1 Answers1

4

The code should look more like this instead:

var
  json         : ISuperObject;
  node         : ISuperObject;
  item         : IMember;
begin
  json := TSuperObject.ParseFile('C:\json.txt', TRUE); 
  for item in json.O['follows'].A['nodes'] do 
  begin
    node := item.AsObject;
    Memo1.Lines.Add(node.S['username']); 
  end;
end;

Or this:

var
  json         : ISuperObject;
  node         : ISuperObject;
  item         : IMember;
begin
  json := TSuperObject.ParseFile('C:\json.txt', TRUE); 
  for item in json['follows.nodes'].AsArray do 
  begin
    node := item.AsObject;
    Memo1.Lines.Add(node.S['username']); 
  end;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • `json['nodes'].AsArray` causes this error `for-in statement cannot operate on collection type 'TSuperArray' because 'TSuperArray' does not contain a member for 'GetEnumerator', or it is inaccessible`. removing `AsArray` causes Access Violation! – ColdZer0 Jun 28 '16 at 02:54
  • 1
    Are you using the [latest version of ISuperObject](https://github.com/delphiframeworks/x-superobject/)? `json['nodes']` returns an `ISuperExpression`, whose `AsArray` property returns an `ISuperArray`, not a `TSuperArray` (`json.A['nodes']` also returns an `ISuperArray`). `ISuperArray` has a `GetEnumerator()` method for use with Delphi `for..in` loops. – Remy Lebeau Jun 28 '16 at 02:59
  • ok, updated the `ISuperObject` now i get `Incompatible types: 'ISuperObject' and 'ICast'` on both ways in your answer – ColdZer0 Jun 28 '16 at 03:10
  • The elements of the enumerator are returned as `ICast`, so change your `row_item` variable to `ICast` (or `IMember`, which is an alias for `ICast`), and then you can use `row_item.AsObject['username'].AsString` or `row_item.AsObject.S['username']`. – Remy Lebeau Jun 28 '16 at 03:17
  • alright, it compiles now, but nothing is added to Memo1!, i opened the debugger and there is no processes added after i click Button1 in the event log – ColdZer0 Jun 28 '16 at 03:24
  • @ColdZer0 why would you expect a new process to be started? There is no process involved. Now, let's start with the obvious- what does your **real** JSON look like? Because what is in your question is invalid JSON. The code in my answer is based on an *assumption* of what the real JSON looks like. Can you confirm it? – Remy Lebeau Jun 28 '16 at 03:42
  • updated the JSON, is there a difference ? @Remy Lebeau – ColdZer0 Jun 28 '16 at 15:19
  • my bad very sorry, this my first time dealing with JSON i thought it wont make a change if i deleted some parts, lesson learned, Thanks for the information and your efforts @Remy Lebeau – ColdZer0 Jun 28 '16 at 15:30
  • @Remy - thanks for your comment. I have deleted my post. Regards. – Dsm Jun 28 '16 at 15:31
  • @ColdZer0: yes, there is a difference, because now the `username` values are located at a different level in the hierarchy, which requires slightly different code to reach. I have updated my answer to compensate for that. – Remy Lebeau Jun 28 '16 at 15:44
  • @RemyLebeau how to `end_cursor` value, i tried `Memo1.Lines.Add(json['followed_by.count..page_info.end_cursor'].AsString);` but i get nothing – ColdZer0 Jun 29 '16 at 03:57
  • @ColdZer0: There is no `followed_by` object in the JSON you showed. The `end_cursor` is a value of the `page_info` object inside the `follows` object: `Memo1.Lines.Add(json['follows.page_info.end_cursor'].AsString);` – Remy Lebeau Jun 29 '16 at 15:52