You are not logged in.
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
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
Sorry, the properties were public rather than published
Offline