skip to Main Content

I’m creating a nested JSON object in Delphi using this code:

   var jo:TJsonObject;

   try
      jo := TJsonObject.Create;

      jo.AddPair('data', TJsonObject.Create);
      with jo.GetValue<TJsonObject>('data') do begin
         jo.AddPair('details', TJSONObject.Create);
         with jo.GetValue<TJsonObject>('details') do begin
            jo.AddPair('foo', 'bar');
         end;
      end;

   finally
      FreeAndNil(jo);
   end;

It works and produces the expected result:

{
  "data": {
    "details": {
      "foo": "bar"
    }
  }
}           

It’s not too ugly, but I’m wondering if there is a nicer way to structure the code so I don’t have to first add each child object and then look it up on the next line using GetValue?

2

Answers


  1. Using Delphi’s built-in TJSONObject framework, the only way to avoid having to lookup a nested object after adding it to the document is to simply not add it to the document until after it has been populated, eg:

    var
      jo, joData, joDetails: TJsonObject;
    
    jo := TJsonObject.Create;
    try
      joDetails := TJSONObject.Create;
      joDetails.AddPair('foo', 'bar');
    
      joData := TJsonObject.Create;
      joData.AddPair('details', joDetails);
    
      jo.AddPair('data', joData);
    
      // use Jo as needed...
    
    finally
      jo.Free;
    end;
    

    That being said, you might consider using TJSONObjectBuilder instead. It’s a bit uglier on the setup and cleanup, but it gives you a more natural interface for building up the document sequentially, eg:

    var
      Builder: TJSONObjectBuilder;
      Writer: TJsonTextWriter;
      StringWriter: TStringWriter;
      StringBuilder: TStringBuilder;
    
    StringBuilder := TStringBuilder.Create;
    StringWriter := TStringWriter.Create(StringBuilder);
    Writer := TJsonTextWriter.Create(StringWriter);
    Writer.Formatting := TJsonFormatting.Indented;
    Builder := TJSONObjectBuilder.Create(Writer);
    
    try
      Builder
        .BeginObject
          .BeginObject('data')
            .BeginObject('details')
              .Add('foo','bar')
            .EndObject
          .EndObject
        .EndObject;
    
      // use StringBuilder.ToString as needed...
    finally
      Builder.Free;
      Writer.Free;
      StringWriter.Free;
      StringBuilder.Free;
    end;
    
    
    Login or Signup to reply.
  2. I’d recommend using the XSuperObject library for handling JSON (https://github.com/onryldz/x-superobject) , I use it for any projects I’m working on that involve manipulating JSON because I find it requires much less boiler plate code than the built in Delphi JSON libraries. The documentation on the respository gives an overview of how to use the library to create complex JSON structures.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search