Home > Software engineering >  Gets only the first value from the JSON array. What should I do?
Gets only the first value from the JSON array. What should I do?

Time:08-19

※Please understand that I am not good at English, so I am using a translator to ask questions.※

You want to import and use all the values in the JSON array.

However, I completed loading after writing the code, but it seems that only the first or last value comes out. Added array number and tried everything, but did not receive any value or an error occurred.

The code to get the value in JSON array was found and used in the Stack Overflow: Delphi parse JSON array or array

The JSON code is a little different from mine, but I modified it a little and it works well. However, I am asking experts because it is absurd to bring up only the first or last value.

//============JSON CODE===============
[
    {
        "VehicleWeight": "3.5톤",
        "AlightArea": "경남 창원시 성산구 남산동",
        "Fee_Driver": "70000",
        "LoadArea": "경남 함안군 산인면",
        "Commission": "0",
        "LiveTime": "2022-08-19 09:39:05",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "",
        "ActionName": "취소",
        "VehicleType": "카고",
        "sk": "data#",
        "OrderCondition": "3",
        "Transport_ID": "B2682B5FC09C4CE38F2F14C84C4829D1",
        "pk": "B2682B5FC09C4CE38F2F14C84C4829D1#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    },
    {
        "VehicleWeight": "5톤축",
        "AlightArea": "경남 함안군 칠서면",
        "Fee_Driver": "130000",
        "LoadArea": "경남 창원시 진해구 가주동",
        "Commission": "0",
        "LiveTime": "2022-08-19 09:00:00",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "목재",
        "ActionName": "취소",
        "VehicleType": "카고",
        "sk": "data#",
        "OrderCondition": "3",
        "Transport_ID": "AB8D6C1ABA30497E95BD6FFF287E47A5",
        "pk": "AB8D6C1ABA30497E95BD6FFF287E47A5#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    },
    {
        "VehicleWeight": "2.5톤",
        "AlightArea": "대구 달성군 유가읍",
        "Fee_Driver": "90000",
        "LoadArea": "경남 함안군 대산면",
        "Commission": "0",
        "LiveTime": "2022-08-19 11:06:24",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "",
        "ActionName": "취소",
        "VehicleType": "카고",
        "sk": "data#",
        "OrderCondition": "3",
        "Transport_ID": "F103B2FC1A8B42C9BCB350A8041BCEA4",
        "pk": "F103B2FC1A8B42C9BCB350A8041BCEA4#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    },
    {
        "VehicleWeight": "5톤",
        "AlightArea": "경남 밀양시 부북면",
        "Fee_Driver": "120000",
        "LoadArea": "경남 창원시 의창구 대원동",
        "Commission": "0",
        "LiveTime": "2022-08-19 09:00:00",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "",
        "ActionName": "취소",
        "VehicleType": "윙바디",
        "sk": "data#",
        "OrderCondition": "3",
        "Transport_ID": "C468AAC449B343CB8CB3349CD9FD46A7",
        "pk": "C468AAC449B343CB8CB3349CD9FD46A7#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    },
    {
        "VehicleWeight": "5톤",
        "AlightArea": "대전 대덕구",
        "Fee_Driver": "220000",
        "LoadArea": "경남 함안군 대산면",
        "Commission": "0",
        "LiveTime": "2022-08-19 10:03:16",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "",
        "ActionName": "취소",
        "VehicleType": "카고",
        "sk": "data#",
        "OrderCondition": "3",
        "Transport_ID": "A89FE76963374084933E89C3BD4CB57C",
        "pk": "A89FE76963374084933E89C3BD4CB57C#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    },
    {
        "VehicleWeight": "5톤",
        "AlightArea": "경북 칠곡군 약목면",
        "Fee_Driver": "120000",
        "LoadArea": "경북 영천시 북안면",
        "Commission": "0",
        "LiveTime": "2022-08-19 09:46:20",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "7.5미터",
        "ActionName": "취소",
        "VehicleType": "윙바디",
        "sk": "data#",
        "OrderCondition": "3",
        "Transport_ID": "846A5E797D9E4A8097D816C83FE0034E",
        "pk": "846A5E797D9E4A8097D816C83FE0034E#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    },
    {
        "VehicleWeight": "5톤",
        "AlightArea": "경기 화성시 서신면",
        "Fee_Driver": "110000",
        "LoadArea": "충남 아산시 둔포면",
        "Commission": "0",
        "LiveTime": "2022-08-19 11:00:00",
        "AlightDate": "2022-08-19",
        "LoadDate": "2022-08-19",
        "GoodName": "",
        "ActionName": "등록",
        "VehicleType": "카고/윙바디",
        "sk": "data#",
        "OrderCondition": "1",
        "Transport_ID": "780F2633C16542809FBB96ADADFFBA35",
        "pk": "780F2633C16542809FBB96ADADFFBA35#owner",
        "MultiLoading": "0",
        "Shipper_Name": "한국거성화물(주)"
    }
]
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, IdSSL , IdSSLOpenSSL, HTTPApp , IdURI,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, System.JSON,
  Vcl.Grids, Data.DB, Vcl.DBGrids;

type
  TForm1 = class(TForm)
    DateTimePicker1: TDateTimePicker;
    Edit1: TEdit;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    StringGrid1: TStringGrid;
    editPK: TEdit;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{Automatic column size adjustment}
procedure AutoSizeGridColumn(Grid : TStringGrid; column : integer);
var
  i : integer;
  temp : integer;
  max : integer;
begin
  max := 0;
  for i := 0 to (Grid.RowCount-1) do
  begin
    // Among the width of each row in the specified column based on Grid Canvas
// The maximum value is determined by the width of the column
    temp := Grid.Canvas.TextWidth(grid.cells[column, i]);
    if temp > max then
      max := temp;
  end;
  Grid.ColWidths[column] := max   Grid.GridLineWidth   20;
end;
{End of autosize Column}
//*************************************************************

//==========================Get JSON array values=========================
function getData(JsonString: String; User: String; Field: String): String;
var
  JSonValue: TJSonValue;
  JsonArray: TJSONArray;
  ArrayElement: TJSonValue;
  FoundValue: TJSonValue;
begin
  Result :='';

  // create TJSonObject from string
  JsonValue := TJSonObject.ParseJSONValue(JsonString);

  // get the array
  JsonArray := JsonValue as TJSONArray;

  // iterate the array
  for ArrayElement in JsonArray do begin
    FoundValue := ArrayElement.FindValue(User);
    if FoundValue <> nil then begin
      Result := ArrayElement.GetValue<string>(Field);
      break;
    end;
  end;
end;
//==========================End of getting JSON array values=========================

procedure TForm1.Button1Click(Sender: TObject);
var
  idhttps: TIdHTTP;
  sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
  lStream : TStringStream;
  JSONValue : TJSONValue;
  JSONArray : TJSONArray;
  JSONObject, JSONdata: TJSONObject;
  JSONCount: integer;
  RESULT : String;
  ArrayElement: TJSonValue;
  FoundValue: TJSonValue;
  i : integer;
begin
  Try
    Result := '';
    idhttps := TIdHTTP.Create();
    lStream := TStringStream.Create(nil);
    sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    Try
      sslIOHandler.SSLOptions.Method := sslvSSLv23;
      sslIOHandler.SSLOptions.Mode := sslmClient;

      idhttps.IOHandler := sslIOHandler;

      // idhttps.Request.CustomHeaders.Add(pAuthorization);
      idhttps.HandleRedirects :=False;
      idhttps.Request.Method := 'GET';
      idhttps.Response.ContentType := 'application/json; charset=utf-8';
      idhttps.ConnectTimeout := 10000;
      idhttps.ReadTimeout := 10000;

      lStream.Position := 0;
      idhttps.Get('insert JSON URL', lStream, []);
    Finally
      Result := TEncoding.UTF8.GetString(lStream.Bytes,0, lStream.Size);
      JsonArray := TJSONObject.ParseJSONValue(Result) as TJSONArray;
      JSONCount := JsonArray.Count;
      StringGrid1.RowCount := JSONCount 1;

      for i := 0 to (jsonCount)-1 do
        for ArrayElement in JsonArray do begin
          StringGrid1.Cells[00,i 1] := getdata(Result, '', 'ActionName');//Status
          StringGrid1.Cells[02,i 1] := getdata(Result, '', 'Shipper_Name');//Company Name
          StringGrid1.Cells[03,i 1] := getdata(Result, '', 'LoadDate');//Different day
          StringGrid1.Cells[04,i 1] := getdata(Result, '', 'LoadArea');//to take over
          StringGrid1.Cells[05,i 1] := getdata(Result, '', 'AlightArea');//Downloading
          StringGrid1.Cells[06,i 1] := getdata(Result, '', 'AlightDate');//Departure Day
          StringGrid1.Cells[07,i 1] := getdata(Result, '', 'VehicleType');//model
          StringGrid1.Cells[08,i 1] := getdata(Result, '', 'VehicleWeight');// tonnage
          StringGrid1.Cells[09,i 1] := getdata(Result, '', 'GoodName');//Cargo information
          StringGrid1.Cells[10,i 1] := getdata(Result, '', 'Fee_Driver');//vehicle freight
          StringGrid1.Cells[11,i 1] := getdata(Result, '', 'Commission');//commission
          StringGrid1.Cells[12,i 1] := getdata(Result, '', 'sk');//pk
          StringGrid1.Cells[13,i 1] := getdata(Result, '', 'pk');//sk

          {if StringGrid1.Cells[13,i 1] = '300016244318#9977' then
          begin
            StringGrid1.Cells[01,i 1] := 'O'//연동화물
          end
          else
          begin
            StringGrid1.Cells[01,i 1] := '';//연동화물
          end;   }
        end;

      {StringGrid1 Auto-Size Cell}
      for i := 0 to StringGrid1.ColCount-1 do
      begin
        AutoSizeGridColumn(StringGrid1, i);
      end;
      {StringGrid1 Auto-Size Cell END}

      FreeAndNil(lStream);
      FreeAndNil(idhttps);
      FreeAndNil(sslIOHandler);

    End;
  except
    on E: EIdHTTPProtocolException do
    begin
      Result := e.ErrorMessage;
      FreeAndNil(idhttps);
      FreeAndNil(sslIOHandler);
    end;

  End;
end;

end.

CodePudding user response:

I see a lot of problems in this code.

In Button1Click(), the outer for loop is unnecessary and should be removed. Between the two for loops, you are re-looping through the same array over and over needlessly. The inner for..in loop will suffice.

Also, it doesn't make sense to have getValue() take the original JSON as a string, as Button1Click() has already parsed it out, just to have getValue() reparse it again again and again. Lots of wasted overhead. You should pass the existing TJSONArray or even the ArrayElement to getValue() (or better, just eliminate getValue() completely and move its logic into Button1Click directly, especially since your call to FindValue(User) doesn't make sense as User is always blank).

Also, getData() and Button1Click() are both leaking the TJSONValue objects that ParseJSONValue() returns.

Also, you should be using the overload of TIdHTTP.Get() that returns a string instead of fills a TStream.

Also, your try..finallys need some cleanup, you are not adequately protecting all of your objects from errors.

With all of that said, try something more like this instead:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, IdSSL , IdSSLOpenSSL, HTTPApp , IdURI,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, System.JSON,
  Vcl.Grids, Data.DB, Vcl.DBGrids;

type
  TForm1 = class(TForm)
    DateTimePicker1: TDateTimePicker;
    Edit1: TEdit;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    StringGrid1: TStringGrid;
    editPK: TEdit;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{Automatic column size adjustment}
procedure AutoSizeGridColumn(Grid : TStringGrid; Column : integer);
var
  i : integer;
  temp : integer;
  max : integer;
begin
  max := 0;
  for i := 0 to Grid.RowCount-1 do
  begin
    // Among the width of each row in the specified column based on Grid Canvas
    // The maximum value is determined by the width of the column
    temp := Grid.Canvas.TextWidth(Grid.Cells[Column, i]);
    if temp > max then
      max := temp;
  end;
  Grid.ColWidths[Column] := max   Grid.GridLineWidth   20;
end;
{End of autosize Column}
//*************************************************************

procedure TForm1.Button1Click(Sender: TObject);
var
  idhttps: TIdHTTP;
  sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
  JSONValue : TJSONValue;
  JSONArray : TJSONArray;
  ArrayElement: TJSONValue;
  i : integer;
begin
  idhttps := TIdHTTP.Create;
  try
    sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idhttps);
    sslIOHandler.SSLOptions.Mode := sslmClient;
    sslIOHandler.SSLOptions.Method := sslvSSLv23;
    idhttps.IOHandler := sslIOHandler;

    // idhttps.Request.CustomHeaders.Add(pAuthorization);
    idhttps.HandleRedirects := False;
    idhttps.ConnectTimeout := 10000;
    idhttps.ReadTimeout := 10000;

    idhttps.HTTPOptions := idhttps.HTTPOptions   [hoNoProtocolErrorException, hoWantProtocolErrorContent];

    Result := idhttps.Get('insert JSON URL');
  finally
    idhttps.Free;
  end;

  JSONValue := TJSONObject.ParseJSONValue(Result);
  try
    JsonArray := JSONValue as TJSONArray;
    StringGrid1.RowCount := JsonArray.Count   1;

    i := 1;
    for ArrayElement in JsonArray do
    begin
      StringGrid1.Cells[00,i] := ArrayElement.GetValue<string>('ActionName','');//Status
      StringGrid1.Cells[02,i] := ArrayElement.GetValue<string>('Shipper_Name','');//Company Name
      StringGrid1.Cells[03,i] := ArrayElement.GetValue<string>('LoadDate','');//Different day
      StringGrid1.Cells[04,i] := ArrayElement.GetValue<string>('LoadArea','');//to take over
      StringGrid1.Cells[05,i] := ArrayElement.GetValue<string>('AlightArea','');//Downloading
      StringGrid1.Cells[06,i] := ArrayElement.GetValue<string>('AlightDate','');//Departure Day
      StringGrid1.Cells[07,i] := ArrayElement.GetValue<string>('VehicleType','');//model
      StringGrid1.Cells[08,i] := ArrayElement.GetValue<string>('VehicleWeight','');// tonnage
      StringGrid1.Cells[09,i] := ArrayElement.GetValue<string>('GoodName','');//Cargo information
      StringGrid1.Cells[10,i] := ArrayElement.GetValue<string>('Fee_Driver','');//vehicle freight
      StringGrid1.Cells[11,i] := ArrayElement.GetValue<string>('Commission','');//commission
      StringGrid1.Cells[12,i] := ArrayElement.GetValue<string>('sk','');//pk
      StringGrid1.Cells[13,i] := ArrayElement.GetValue<string>('pk','');//sk

      {if StringGrid1.Cells[13,i] = '300016244318#9977' then
      begin
        StringGrid1.Cells[01,i] := 'O'//연동화물
      end else begin
        StringGrid1.Cells[01,i] := '';//연동화물
      end;}
      
      Inc(i);
    end;
  finally
    JSONValue.Free;
  end;

  {StringGrid1 Auto-Size Cell}
  for i := 0 to StringGrid1.ColCount-1 do
  begin
    AutoSizeGridColumn(StringGrid1, i);
  end;
  {StringGrid1 Auto-Size Cell END}
end;

end.
  • Related