8

My current code:

procedure TForm1.Button10Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
  JSON: string;
  jsonObiekt: TJSONObject;
  streams: TJSONValue;
  liczbaStrumieni: integer;
  i: integer;
begin
  IdHTTP := TIdHTTP.Create;
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
    IdHTTP.IOHandler := IdSSL;
    IdHTTP.Request.CustomHeaders.AddValue('Accept', 'application/vnd.twitchtv.v3+json');
    IdHTTP.Request.CustomHeaders.AddValue('Client-ID', 'smb61nyd0vxmqdn9d3k735qbx41cdyg');
    JSON := IdHTTP.Get('https://api.twitch.tv/kraken/streams?game=StarCraft:%20Brood%20War');
  finally
    IdHTTP.Free;
  end;
  jsonObiekt := nil;
  try
    jsonObiekt := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(JSON), 0) as TJSONObject;
    streams := jsonObiekt.Get('streams').JsonValue;
    liczbaStrumieni := TJSONArray(streams).Size;
    for i := 0 to liczbaStrumieni - 1 do
    begin
      Memo6.Lines.Add(TJSONObject(TJSONArray(streams).Get(i)).Get('viewers').JsonValue.Value);
    end;
  finally
    jsonObiekt.Free;
  end;
end;

With this code i am able to get viewers for every entries in "streams" enter image description here

My goal is to get "status" from "channel", but thats too hard for me. Tried learn from this How to parse nested JSON object in Delphi XE2? but no result, still dont understand it well. Thanks for help.

1 Answer 1

10

It helps to break up the subobjects into their own variables, don't try to do everything in a single statement. Try this:

procedure TForm1.Button10Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
  JSON: string;
  jsonObiekt: TJSONObject;
  streams: TJSONArray;
  stream: TJSONObject;
  channel: TJSONObject;
  status: TJSONString;
  liczbaStrumieni: integer;
  i: integer;
begin
  IdHTTP := TIdHTTP.Create;
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
    IdHTTP.IOHandler := IdSSL;
    IdHTTP.Request.Accept := 'application/vnd.twitchtv.v3+json';
    IdHTTP.Request.CustomHeaders.AddValue('Client-ID', 'smb61nyd0vxmqdn9d3k735qbx41cdyg');
    JSON := IdHTTP.Get('https://api.twitch.tv/kraken/streams?game=StarCraft:%20Brood%20War');
  finally
    IdHTTP.Free;
  end;
  jsonObiekt := TJSONObject.ParseJSONValue(JSON) as TJSONObject;
  try
    streams := jsonObiekt.Get('streams').JsonValue as TJSONArray;
    liczbaStrumieni := streams.Size;
    for i := 0 to liczbaStrumieni - 1 do
    begin
      stream := streams.Get(i) as TJSONObject;
      channel := stream.Get('channel').JsonValue as TJSONObject;
      status := channel.Get('status').JsonValue as TJSONString;
      Memo6.Lines.Add(status.Value);
    end;
  finally
    jsonObiekt.Free;
  end;
end;

Alternatively, download the JSON as bytes so TIdHTTP will not decode them to UTF-16, and thus TJSONObject can parse the original bytes as-is:

procedure TForm1.Button10Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
  JSON: TBytesStream;
  jsonObiekt: TJSONObject;
  streams: TJSONArray;
  stream: TJSONObject;
  channel: TJSONObject;
  status: TJSONString;
  liczbaStrumieni: integer;
  i: integer;
begin
  jsonObiekt := nil;
  try
    JSON := TBytesStream.Create;
    try
      IdHTTP := TIdHTTP.Create;
      try
        IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
        IdHTTP.IOHandler := IdSSL;
        IdHTTP.Request.Accept := 'application/vnd.twitchtv.v3+json';
        IdHTTP.Request.CustomHeaders.AddValue('Client-ID', 'smb61nyd0vxmqdn9d3k735qbx41cdyg');
        IdHTTP.Get('https://api.twitch.tv/kraken/streams?game=StarCraft:%20Brood%20War', JSON);
      finally
        IdHTTP.Free;
      end;
      jsonObiekt := TJSONObject.ParseJSONValue(JSON.Bytes, 0, JSON.Size) as TJSONObject;
    finally
      JSON.Free;
    end;
    streams := jsonObiekt.Get('streams').JsonValue as TJSONArray;
    liczbaStrumieni := streams.Size;
    for i := 0 to liczbaStrumieni - 1 do
    begin
      stream := streams.Get(i) as TJSONObject;
      channel := stream.Get('channel').JsonValue as TJSONObject;
      status := channel.Get('status').JsonValue as TJSONString;
      Memo6.Lines.Add(status.Value);
   end;
  finally
    jsonObiekt.Free;
  end;
end;
Sign up to request clarification or add additional context in comments.

1 Comment

TBytesStream, missing a 's'

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.