Skip to main content

JsonHelper220FDW

Utility codeunit for safe reading and writing of JSON objects. Provides typed accessors with optional error handling, upsert-style writers, and array manipulation helpers. Used extensively by MobileRPCState220FDW internally, and available for use in your own service code.

Overview

  • Object type: Codeunit
  • Object ID: 73167875
  • Access: Public
  • Namespace: Aptean.Mesh.SDUI

All read methods accept a ShowError parameter. When true, a missing key raises an error:

Required parameter "%1" is missing

When false, the method returns the type's default value (e.g., 0 for Integer, '' for Text, false for Boolean).

All write methods use upsert semantics -- they replace the value if the key already exists, or add it if it does not.


Read Methods

ReadInteger

procedure ReadInteger(JObj: JsonObject; KeyName: Text; ShowError: Boolean): Integer

Reads an integer value from a JSON object.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ShowErrorBooleanIf true, throws an error when the key is missing

Returns: Integer -- the value, or 0 if not found and ShowError is false.


ReadText

procedure ReadText(JObj: JsonObject; KeyName: Text; ShowError: Boolean): Text

Reads a text value from a JSON object.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ShowErrorBooleanIf true, throws an error when the key is missing

Returns: Text -- the value, or '' if not found and ShowError is false.


ReadDecimal

procedure ReadDecimal(JObj: JsonObject; KeyName: Text; ShowError: Boolean): Decimal

Reads a decimal value from a JSON object.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ShowErrorBooleanIf true, throws an error when the key is missing

Returns: Decimal -- the value, or 0 if not found and ShowError is false.


ReadGuid

procedure ReadGuid(JObj: JsonObject; KeyName: Text; ShowError: Boolean): Guid

Reads a GUID value from a JSON object. The value is stored as text in the JSON and parsed using Evaluate.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ShowErrorBooleanIf true, throws an error when the key is missing

Returns: Guid -- the parsed GUID, or an empty GUID if not found and ShowError is false.


ReadBoolean

procedure ReadBoolean(JObj: JsonObject; KeyName: Text; ShowError: Boolean): Boolean

Reads a boolean value from a JSON object.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ShowErrorBooleanIf true, throws an error when the key is missing

Returns: Boolean -- the value, or false if not found and ShowError is false.


ReadDate

procedure ReadDate(JObj: JsonObject; KeyName: Text; ShowError: Boolean): Date

Reads an ISO 8601 date string (YYYY-MM-DD) from a JSON object and returns it as an AL Date. Always use this method instead of ReadText followed by manual parsing — ReadText is locale-agnostic but format parsing is fragile.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ShowErrorBooleanIf true, throws an error when the key is missing

Returns: Date -- the parsed date, or 0D if not found and ShowError is false.

Always pair with WriteDate

Dates on the wire must be ISO 8601 strings. ReadDate expects exactly the format that WriteDate produces. Never write dates with Format(Date) — the locale-sensitive output will fail to parse.


ReadObject

procedure ReadObject(JObj: JsonObject; KeyName: Text; var Result: JsonObject): Boolean

Tries to read a nested JSON object from the parent object.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ResultJsonObjectvar -- receives the nested object if found

Returns: Boolean -- true if the key was found and contained an object, false otherwise.

Example:

var
JsonHelper: Codeunit JsonHelper220FDW;
ParentObj, ChildObj : JsonObject;
begin
if JsonHelper.ReadObject(ParentObj, 'address', ChildObj) then
City := JsonHelper.ReadText(ChildObj, 'city', false);
end;

ReadArray

procedure ReadArray(JObj: JsonObject; KeyName: Text; var Result: JsonArray): Boolean

Tries to read a JSON array from the parent object.

Parameters:

NameTypeDescription
JObjJsonObjectThe JSON object to read from
KeyNameTextThe key to look up
ResultJsonArrayvar -- receives the array if found

Returns: Boolean -- true if the key was found and contained an array, false otherwise.


Write Methods

All write methods use upsert semantics: if the key already exists, the value is replaced; if not, it is added.

WriteInteger

procedure WriteInteger(var JObj: JsonObject; KeyName: Text; Value: Integer)

Writes an integer value to a JSON object.

Parameters:

NameTypeDescription
JObjJsonObjectvar -- the JSON object to write to
KeyNameTextThe key to set
ValueIntegerThe value to write

WriteText

procedure WriteText(var JObj: JsonObject; KeyName: Text; Value: Text)

Writes a text value to a JSON object.


WriteBoolean

procedure WriteBoolean(var JObj: JsonObject; KeyName: Text; Value: Boolean)

Writes a boolean value to a JSON object.


WriteDecimal

procedure WriteDecimal(var JObj: JsonObject; KeyName: Text; Value: Decimal)

Writes a decimal value to a JSON object as a native JSON number (not a string). The mobile client performs arithmetic on decimal fields — always use this method instead of WriteText(Format(Qty)).


WriteDate

procedure WriteDate(var JObj: JsonObject; KeyName: Text; Value: Date)

Writes an AL Date as an ISO 8601 string (YYYY-MM-DD) to a JSON object. Always use this method for date fields — Format(Date) is locale-sensitive and will produce different strings on different BC servers, breaking client parsing.

Parameters:

NameTypeDescription
JObjJsonObjectvar — the JSON object to write to
KeyNameTextThe key to set
ValueDateThe date to write. 0D is written as an empty string "".

Example:

var
JsonHelper: Codeunit JsonHelper220FDW;
Result: JsonObject;
begin
// ✅ Writes: "expiryDate": "2025-12-31"
JsonHelper.WriteDate(Result, 'expiryDate', ExpiryDate);

// ❌ Wrong — locale-sensitive, breaks client parsing in nl-NL
JsonHelper.WriteText(Result, 'expiryDate', Format(ExpiryDate));
end;

WriteObject

procedure WriteObject(var JObj: JsonObject; KeyName: Text; Value: JsonObject)

Writes a nested JSON object to the parent object.


WriteArray

procedure WriteArray(var JObj: JsonObject; KeyName: Text; Value: JsonArray)

Writes a JSON array to the parent object.


Utility Methods

RemoveKey

procedure RemoveKey(var JObj: JsonObject; KeyName: Text)

Removes a key from the JSON object if it exists. No error is raised if the key is not found.

Parameters:

NameTypeDescription
JObjJsonObjectvar -- the JSON object to modify
KeyNameTextThe key to remove

MergeInto

procedure MergeInto(var TargetObj: JsonObject; SourceObj: JsonObject)

Merges all keys from the source object into the target object. Existing keys in the target are overwritten with values from the source.

Parameters:

NameTypeDescription
TargetObjJsonObjectvar -- the target object that receives merged keys
SourceObjJsonObjectThe source object whose keys are copied

Example:

var
JsonHelper: Codeunit JsonHelper220FDW;
Base, Overrides : JsonObject;
begin
// Base: { "color": "red", "size": 10 }
// Overrides: { "color": "blue", "weight": 5 }
JsonHelper.MergeInto(Base, Overrides);
// Result: { "color": "blue", "size": 10, "weight": 5 }
end;

Array Methods

UpdateArrayField

procedure UpdateArrayField(
var JArr: JsonArray;
SearchField: Text;
SearchValue: Text;
UpdateField: Text;
NewValue: Text): Boolean

Finds the first object in the array where SearchField equals SearchValue, then sets UpdateField to NewValue.

Parameters:

NameTypeDescription
JArrJsonArrayvar -- the array to search and update
SearchFieldTextThe field name to match on
SearchValueTextThe value to match
UpdateFieldTextThe field to update in the matched object
NewValueTextThe new value to set

Returns: Boolean -- true if a matching item was found and updated, false otherwise.

Example:

var
JsonHelper: Codeunit JsonHelper220FDW;
Fields: JsonArray;
begin
// Update the "Bin" field's value to "BIN-05" in the info pane fields array
JsonHelper.UpdateArrayField(Fields, 'label', 'Bin', 'value', 'BIN-05');
end;

ArrayContainsField

procedure ArrayContainsField(JArr: JsonArray; SearchField: Text; SearchValue: Text): Boolean

Checks if the array contains an object where SearchField equals SearchValue.

Parameters:

NameTypeDescription
JArrJsonArrayThe array to search
SearchFieldTextThe field name to match on
SearchValueTextThe value to match

Returns: Boolean -- true if a matching item exists.


UpdateArrayFieldWithGauge

procedure UpdateArrayFieldWithGauge(
var JArr: JsonArray;
SearchField: Text;
SearchValue: Text;
ValueField: Text;
NewValue: Text;
GaugeField: Text;
GaugeValue: Integer): Boolean

Similar to UpdateArrayField, but also sets a gauge field (0--100) on the matched object. The gauge field is only updated if it already exists on the object.

Parameters:

NameTypeDescription
JArrJsonArrayvar -- the array to search and update
SearchFieldTextThe field name to match on
SearchValueTextThe value to match
ValueFieldTextThe field to update with NewValue
NewValueTextThe new text value
GaugeFieldTextThe gauge field to update (0--100)
GaugeValueIntegerThe new gauge percentage

Returns: Boolean -- true if a matching item was found and updated.

Example:

var
JsonHelper: Codeunit JsonHelper220FDW;
Fields: JsonArray;
Percent: Integer;
begin
Percent := Round(ScannedQty / TotalQty * 100, 1);
JsonHelper.UpdateArrayFieldWithGauge(
Fields, 'label', 'Scanned Qty',
'value', Format(ScannedQty),
'gauge', Percent);
end;

Common Usage Patterns

Reading required vs. optional fields

var
JsonHelper: Codeunit JsonHelper220FDW;
RequestData: JsonObject;
begin
// Required -- throws an error if missing
DocumentNo := JsonHelper.ReadText(RequestData, 'documentNo', true);

// Optional -- returns '' if missing
Notes := JsonHelper.ReadText(RequestData, 'notes', false);
end;

Building a response object

var
JsonHelper: Codeunit JsonHelper220FDW;
Response, Details : JsonObject;
Items: JsonArray;
begin
JsonHelper.WriteText(Response, 'status', 'OK');
JsonHelper.WriteInteger(Response, 'totalCount', 42);
JsonHelper.WriteBoolean(Response, 'hasMore', false);
JsonHelper.WriteObject(Response, 'details', Details);
JsonHelper.WriteArray(Response, 'items', Items);
end;

Safely reading nested objects

var
JsonHelper: Codeunit JsonHelper220FDW;
Root, Address : JsonObject;
begin
if JsonHelper.ReadObject(Root, 'shippingAddress', Address) then begin
City := JsonHelper.ReadText(Address, 'city', false);
PostCode := JsonHelper.ReadText(Address, 'postCode', false);
end;
end;

See Also