Comprehensive guide to JSON handling in Delphi VCL and TMS WEB Core (pas2js) applications.
Standard Delphi uses System.JSON unit with TJSONObject, TJSONArray, TJSONValue classes.
USES System.JSON;
VAR
JSONObj: TJSONObject;
JSONValue: TJSONValue;
Name: STRING;
Age: Integer;
BEGIN
JSONValue := TJSONObject.ParseJSONValue(JSONString);
TRY
IF JSONValue IS TJSONObject THEN
BEGIN
JSONObj := JSONValue AS TJSONObject;
Name := JSONObj.GetValue<STRING>('name');
Age := JSONObj.GetValue<Integer>('age');
END;
FINALLY
JSONValue.Free;
END;
END;
VAR
JSONObj: TJSONObject;
JSONArray: TJSONArray;
BEGIN
JSONObj := TJSONObject.Create;
TRY
JSONObj.AddPair('name', 'John');
JSONObj.AddPair('age', TJSONNumber.Create(30));
JSONArray := TJSONArray.Create;
JSONArray.Add('item1');
JSONArray.Add('item2');
JSONObj.AddPair('items', JSONArray);
Result := JSONObj.ToJSON;
FINALLY
JSONObj.Free; /// Frees child objects too
END;
END;
TMS WEB Core uses native JavaScript objects via the JS unit. Different approach from VCL.
| Type | Description |
|---|---|
TJSObject | JavaScript object (key-value pairs) |
TJSArray | JavaScript array |
TJSJSON | JSON parsing/stringifying class |
JSValue | Any JavaScript value |
USES JS, Web;
VAR
Obj: TJSObject;
Name: STRING;
Age: Integer;
BEGIN
Obj := TJSJSON.parseObject(JSONString);
Name := STRING(Obj['name']);
Age := Integer(Obj['age']);
END;
VAR
Obj: TJSObject;
Arr: TJSArray;
JSONString: STRING;
BEGIN
Obj := TJSObject.new;
Obj['name'] := 'John';
Obj['age'] := 30;
Arr := TJSArray.new;
Arr.push('item1');
Arr.push('item2');
Obj['items'] := Arr;
JSONString := TJSJSON.stringify(Obj);
END;
/// Check if property exists
IF Obj.hasOwnProperty('optionalField') THEN
Value := STRING(Obj['optionalField'])
ELSE
Value := 'default';
/// Or use JS undefined check
IF NOT isUndefined(Obj['optionalField']) THEN
Value := STRING(Obj['optionalField']);
/// TMS Web Core
VAR
Config: TJSObject;
Database: TJSObject;
Host: STRING;
BEGIN
Config := TJSJSON.parseObject(JSONString);
Database := TJSObject(Config['database']);
Host := STRING(Database['host']);
END;
/// TMS Web Core - explicit casts required
IntValue := Integer(Obj['count']); /// Number to Integer
FloatValue := Double(Obj['price']); /// Number to Double
StrValue := STRING(Obj['name']); /// String
BoolValue := Boolean(Obj['active']); /// Boolean
ArrValue := TJSArray(Obj['items']); /// Array
ObjValue := TJSObject(Obj['nested']); /// Object
/// Using TJSObject.new
VAR
Obj: TJSObject;
BEGIN
Obj := TJSObject.new;
Obj['id'] := 123;
Obj['name'] := 'Test';
Obj['enabled'] := True;
Obj['tags'] := TJSArray._of('tag1', 'tag2', 'tag3');
END;
/// Parse a template and modify
VAR
Template: TJSObject;
BEGIN
Template := TJSJSON.parseObject('{
"type": "card",
"width": 300,
"height": 200
}');
Template['width'] := 400; /// Override
END;
VAR
Arr: TJSArray;
Index: Integer;
Item: TJSObject;
BEGIN
Arr := TJSArray(Obj['items']);
FOR Index := 0 TO Arr.Length - 1 DO
BEGIN
Item := TJSObject(Arr[Index]);
ProcessItem(STRING(Item['name']));
END;
END;
/// Empty array
Arr := TJSArray.new;
/// With initial values
Arr := TJSArray._of(1, 2, 3, 4, 5);
Arr := TJSArray._of('a', 'b', 'c');
/// Push items
Arr.push(NewItem);
Arr.push(TJSObject.new); /// Push object
Arr.Length; /// Number of items
Arr.push(Item); /// Add to end
Arr.pop; /// Remove from end
Arr.shift; /// Remove from start
Arr.unshift(Item); /// Add to start
Arr.splice(2, 1); /// Remove 1 item at index 2
/// VCL - TJSONObject owns children, Free once
JSONObj := TJSONObject.ParseJSONValue(Str) AS TJSONObject;
TRY
/// Use JSONObj
FINALLY
JSONObj.Free;
END;
/// TMS Web Core - JavaScript GC handles cleanup
Obj := TJSJSON.parseObject(Str);
/// Just use it, no Free needed
{$IFDEF PAS2JS}
/// TMS Web Core version
Obj := TJSJSON.parseObject(JSONString);
Value := STRING(Obj['field']);
{$ELSE}
/// VCL version
JSONObj := TJSONObject.ParseJSONValue(JSONString) AS TJSONObject;
TRY
Value := JSONObj.GetValue<STRING>('field');
FINALLY
JSONObj.Free;
END;
{$ENDIF}