jsonrestdelphitclientdataset

What is the proper way to retrieve a nested JSON field using TClientDataset in Delphi?


I am using TRestClient>TRestRequest>TRestResponse>TRESTResponseDataSetAdapter to retrieve JSON data from a Rest API. This works well and I create a TClientDataset in memory:

  // Create a new in memory dataset
  gStaffTable := TClientDataset.Create(nil);

  with gStaffTable do
  begin
    // Add some fields to it
    FieldDefs.Add('FirstName', ftString, 255, False);         //0
    FieldDefs.Add('MiddleName', ftString, 255, False);        //1
    FieldDefs.Add('LastName', ftString, 255, False);          //2
    // ...add the other fields 3..26 here
    // Department is a nested field
    FieldDefs.Add('Department', ftString, 255, False);        //27

    // Create it
    CreateDataSet;
    // Add an AfterScroll procedure
    AfterScroll := gStaffTableAfterScroll;
    OnCalcFields := gStaffTableOnCalcFields;

    IndexFieldNames := 'FullName';
    Open;
    FieldByName('Firstname').DisplayLabel := 'First Name';
    FieldByName('MiddleName').DisplayLabel := 'Middle Name';
    //.. add the rest of the displaylabels here
 
   end;

I can then read my data into the fields:

  ClientDataset.First;
  while not ClientDataSet.EOF do
  begin
    with gStaffTable do
    begin
      try
        application.ProcessMessages;
        append;
          FieldbyName('Firstname').AsString := ClientDataSetfirst_name.AsString;
          FieldbyName('LastName').AsString := ClientDataSetlast_name.AsString;
          FieldbyName('Fullname').AsString := ClientDataSetfirst_name.AsString + ' ' + 
          //.. do the same for the rest of the fields
          
          // Department is a nested field - need to modify this to read the department name
          // {"name":"Finance","id":29111}
          FieldbyName('Department').AsString :=  ClientDataSet.FieldByName('Department').AsString;

        post;
      except

      end;
    end;
    application.ProcessMessages;
    ClientDataSet.Next;
  end;

I can then just assign the DataField to a component on the GUI (partial screen snip):

enter image description here

You can see from this what my problem is. The Department field is a nested element and I cannot figure out how to access {"name":"Finance","id":29111} to display Finance.

I have tried various resolutions to similar problems but cannot find one that works.


Solution

  • You can use the TJSONObject.ParseJSONValue class function for parsing the JSON string.

    For example, you can define a function to extract the value:

    uses
      System.JSON;
    
    function ExtractPairStringValue(const AJSONString : string; const APairName : string) : string;
    var
      Obj : TJSONValue;
    begin
      Obj := TJSONObject.ParseJSONValue(AJSONString);
      try
        Result := Obj.GetValue<string>(APairName);
      finally
        Obj.Free;
      end;
    end;
    

    Then you'll be able to extract the value like this:

    FieldByName('Department').AsString := ExtractPairStringValue(ClientDataSet.FieldByName('Department').AsString, 'name');