#1 2017-05-06 20:20:49

edismo
Member
From: Brazil
Registered: 2013-10-04
Posts: 34

SynCrossPlatformJSON - Null json TInterfacedCollection with 2 levels

Hello AB,

I try to generate json (with multiple levels of collections), but, level 2 is generated null.
Can you help me?

The example is below.

My Unit

unit UnitSample;

interface

uses
  System.Classes,
  mORMot,
  SynCommons;

type

  TLevel3 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level2: Integer;
    FName: RawUTF8;
  public
    property ID: Integer read FID write FID;
    property ID_Level2: Integer read FID_Level2 write FID_Level2;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel3 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel3;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel3 read GetCollItem; default;
      function Add: TLevel3;
  end;

  TLevel2 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level1: Integer;
    FName: RawUTF8;
    FListLevel3: TListLevel3;
  public
    property ID: Integer read FID write FID;
    property ID_Level1: Integer read FID_Level1 write FID_Level1;
    property Name: RawUTF8 read FName write FName;
    property ListLevel3: TListLevel3 read FListLevel3 write FListLevel3;
    destructor Destroy; override;
  end;

  TListLevel2 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel2;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel2 read GetCollItem; default;
      function Add: TLevel2;
  end;

  TLevel1 = class(TCollectionItem)
  private
    FID: Integer;
    FID_AnyProp1: Integer;
    FName: RawUTF8;
    FListLevel2: TListLevel2;
  published
    property ID: Integer read FID write FID;
    property ID_AnyProp1: Integer read FID_AnyProp1 write FID_AnyProp1;
    property Name: RawUTF8 read FName write FName;
    property ListLevel2: TListLevel2 read FListLevel2 write FListLevel2;
    destructor Destroy; override;
  end;

  TListLevel1 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel1;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel1 read GetCollItem; default;
      function Add: TLevel1;
  end;

  TLevel0 = class
   private
      FID: Integer;
      FName: RawUTF8;
      FListLevel1: TListLevel1;
    published
      property ID   : Integer  read FID   write FID;
      property Name : RawUTF8  read FName write FName;
      property ListLevel1: TListLevel1 read FListLevel1 write FListLevel1;
      constructor Create;
      destructor Destroy; override;
  end;

implementation

uses
  SysUtils;

{ TListLevel1 }

function TListLevel1.Add: TLevel1;
begin
  result := TLevel1(inherited Add);
  result.FListLevel2 := TListLevel2.Create;
end;

class function TListLevel1.GetClass: TCollectionItemClass;
begin
  result := TLevel1;
end;

function TListLevel1.GetCollItem(aIndex: Integer): TLevel1;
begin
  result := TLevel1(GetItem(aIndex));
end;

{ TListLevel2 }

function TListLevel2.Add: TLevel2;
begin
  result := TLevel2(inherited Add);
  result.FListLevel3 := TListLevel3.Create;
end;

class function TListLevel2.GetClass: TCollectionItemClass;
begin
  result := TLevel2;
end;

function TListLevel2.GetCollItem(aIndex: Integer): TLevel2;
begin
  result := TLevel2(GetItem(aIndex));
end;

{ TListLevel3 }

function TListLevel3.Add: TLevel3;
begin
  result := TLevel3(inherited Add);
end;

class function TListLevel3.GetClass: TCollectionItemClass;
begin
  result := TLevel3;
end;

function TListLevel3.GetCollItem(aIndex: Integer): TLevel3;
begin
  result := TLevel3(GetItem(aIndex));
end;

{ TLevel0 }

constructor TLevel0.Create;
begin
  FListLevel1 := TListLevel1.Create;
end;

destructor TLevel0.Destroy;
begin
  FreeAndNil(FListLevel1);
  inherited;
end;

{ TLevel1 }

destructor TLevel1.Destroy;
begin
  FreeAndNil(FListLevel2);
  inherited;
end;

{ TLevel2 }

destructor TLevel2.Destroy;
begin
  FreeAndNil(FListLevel3);
  inherited;
end;

end.

Values of sample

var
  Level0: TLevel0;
  LocalJson: RawJSON;
begin
  Level0 := TLevel0.Create;
  try
    Level0.ID := 1;
    Level0.Name := 'ANY TEXT LEVEL 0';

    with TLevel1(Level0.ListLevel1.Add) do
    begin
      ID := 1;
      ID_AnyProp1 := Level0.ID;
      Name := 'ANY TEXT LEVEL 1';

      with TLevel2(ListLevel2.Add) do
      begin
        ID := 1;
        ID_Level1 := 1;
        Name := 'ANY TEXT LEVEL 2';
        with TLevel3(ListLevel3.Add) do
        begin
          ID := 1;
          ID_Level2 := 1;
          Name := 'ANY TEXT LEVEL 3 A';
        end;
        with TLevel3(ListLevel3.Add) do
        begin
          ID := 2;
          ID_Level2 := 1;
          Name := 'ANY TEXT LEVEL 3 B';
        end;
      end;
    end;
    LocalJson := ObjectToJson(Level0);

    Memo.Text := LocalJson;
  finally
    FreeAndNil(Level0);
  end;

JSON gerated

{
  "ID": 1,
  "Name": "ANY TEXT LEVEL 0",
  "ListLevel1": [
    {
      "ID": 1,
      "ID_AnyProp1": 1,
      "Name": "ANY TEXT LEVEL 1",
      "ListLevel2": [
        null
      ]
    }
  ]
}


      "ListLevel2": [
        null
      ]

Offline

#2 2017-05-06 22:16:07

edismo
Member
From: Brazil
Registered: 2013-10-04
Posts: 34

Re: SynCrossPlatformJSON - Null json TInterfacedCollection with 2 levels

I tried to tailor the example below, but also returned null for additional collections.

  TLevel3 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level2: Integer;
    FName: RawUTF8;
  public
    property ID: Integer read FID write FID;
    property ID_Level2: Integer read FID_Level2 write FID_Level2;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel3 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel3;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel3 read GetCollItem; default;
      function Add: TLevel3;
  end;

  TLevel2 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level1: Integer;
    FName: RawUTF8;
  public
    property ID: Integer read FID write FID;
    property ID_Level1: Integer read FID_Level1 write FID_Level1;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel2 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel2;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel2 read GetCollItem; default;
      function Add: TLevel2;
  end;

  TLevel1 = class(TCollectionItem)
  private
    FID: Integer;
    FID_AnyProp1: Integer;
    FName: RawUTF8;
  published
    property ID: Integer read FID write FID;
    property ID_AnyProp1: Integer read FID_AnyProp1 write FID_AnyProp1;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel1 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel1;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel1 read GetCollItem; default;
      function Add: TLevel1;
  end;

  TLevel0 = class
   private
      FID: Integer;
      FName: RawUTF8;
      FListLevel1: TListLevel1;
      FListLevel2: TListLevel2;
      FListLevel3: TListLevel3;
    published
      property ID   : Integer  read FID   write FID;
      property Name : RawUTF8  read FName write FName;
      property ListLevel1: TListLevel1 read FListLevel1 write FListLevel1;
      property ListLevel2: TListLevel2 read FListLevel2 write FListLevel2;
      property ListLevel3: TListLevel3 read FListLevel3 write FListLevel3;
      constructor Create;
      destructor Destroy; override;
  end;

JSON

{
  "ID": 1,
  "Name": "ANY TEXT LEVEL 0",
  "ListLevel1": [
    {
      "ID": 1,
      "ID_AnyProp1": 1,
      "Name": "ANY TEXT LEVEL 1"
    }
  ],
  "ListLevel2": [
    null
  ],
  "ListLevel3": [
    null,
    null
  ]
}

Offline

#3 2017-05-08 02:33:38

edismo
Member
From: Brazil
Registered: 2013-10-04
Posts: 34

Re: SynCrossPlatformJSON - Null json TInterfacedCollection with 2 levels

Sorry, the properties were public rather than published

Offline

Board footer

Powered by FluxBB