Generating JSON in AL

jonathanchye
jonathanchye Member Posts: 34
I've found some a few resources which has basics of generating a JSON file using JsonObject in AL.
One helpful link is : https://community.dynamics.com/business/f/dynamics-365-business-central-forum/289143/creating-json-data-in-al-jsonobjectclass

However I'm not sure on how to generate nested objects.
Example would be:
{
  "order": {
    "orderSessionId": "uf3343d98weicsc445dd4",
    "orderId": "O0123456",
    "createdAt": "2018-07-11T17:54:31-05:00",
    "currency": "GNP",
    "orderChannel": "WEB",
    "receivedBy": "John Doe",
    "totalPrice": 72.99
	}
}

I'm can generate the objects i.e. orderSessionID, orderID etc using JsonObject.Add('orderSessionID', 'value') but not sure how to nest it within order object.

Can anyone please assist?

Answers

  • ftornero
    ftornero Member Posts: 524
    Hello @jonathanchye

    You can use this:
        var
            OrderBody: JsonObject;
            OrderDetail: JsonObject;
    
        begin
            OrderDetail.Add('orderSessionId', 'uf3343d98weicsc445dd4');
            OrderDetail.Add('orderId', 'O0123456');
            OrderDetail.Add('createdAt', '2018-07-11T17:54:31-05:00');
            OrderDetail.Add('currency', 'GNP');
            OrderDetail.Add('orderChannel', 'WEB');
            OrderDetail.Add('receivedBy', 'John Doe');
            OrderDetail.Add('totalPrice', '72.99');
    
            OrderBody.Add('Order', OrderDetail.AsToken());
        end;
    

    Regards
  • jonathanchye
    jonathanchye Member Posts: 34
    Ok, think I've cracked it. To achieve the above I needed to pass the order details Json object into a parent object.

    So something like
            orderObject.Add('orderSessionID', 'uf3343d98weicsc445dd4');
            orderObject.Add('orderID', SalesOrder."No.");
            orderObject.Add('totalPrice', SalesLine.Amount);
            orderObjectHeader.add('order', orderObject);
            orderObjectHeader.WriteTo(Output);
    
  • jonathanchye
    jonathanchye Member Posts: 34
    ftornero wrote: »
    Hello @jonathanchye

    You can use this:
        var
            OrderBody: JsonObject;
            OrderDetail: JsonObject;
    
        begin
            OrderDetail.Add('orderSessionId', 'uf3343d98weicsc445dd4');
            OrderDetail.Add('orderId', 'O0123456');
            OrderDetail.Add('createdAt', '2018-07-11T17:54:31-05:00');
            OrderDetail.Add('currency', 'GNP');
            OrderDetail.Add('orderChannel', 'WEB');
            OrderDetail.Add('receivedBy', 'John Doe');
            OrderDetail.Add('totalPrice', '72.99');
    
            OrderBody.Add('Order', OrderDetail.AsToken());
        end;
    

    Regards

    Thanks! I've used a slightly different method but yours is definitely cleaner :)
  • jonathanchye
    jonathanchye Member Posts: 34
    I have 2 more questions please:

    1) Passing Null value : How is this done?
    OrderDetail.Add('itemWeight', 'null')
    
    creates string value of "null" in the JSON

    2) Formatting : I've tried to remove decimals using code below however the JSON output converts the value to string. How can I remove the decimal whilst retaining the number property?
    OrderDetail.Add('itemWeight',FORMAT(item."Gross Weight"/1000,0,'<integer>')
    
  • ftornero
    ftornero Member Posts: 524
    Hello @jonathanchye.

    You can add a new var like this
            jsValue: JsonValue;
    

    And use it like this:
            jsValue.ReadFrom('72.99');
            OrderDetail.Add('totalPrice', jsValue.AsDecimal());
    
            jsValue.SetValueToNull();
            OrderDetail.Add('itemWeight', jsValue.AsToken());
    

    Regards
  • jonathanchye
    jonathanchye Member Posts: 34
    edited 2019-08-15
    @ftornero Many thanks the SetValueToNull worked brilliantly!

    Regarding the decimals I think I haven't described it clearly.

    As an example the code below gives a value of 1,234.0 (numeric) in the JSON output.
    OrderDetail.Add('Quantity', SalesLine.Quantity);
    

    How do I format it so that it returns 1234 (numeric) in the JSON output?

    I've tried the below but the output in JSON is string, enclosed in double quotes.
    OrderDetail.Add('Quantity', format(SalesLine.Quantity,0,'<integer>');
    
  • ftornero
    ftornero Member Posts: 524
    Hello @jonathanchye ,

    In that case you need to do this:
            var
              xValue: Decimal;
              txtValue: Text;
    
            xValue := 72.99;
            txtValue := DelChr(format(xValue), '=', '.');
            txtValue := ConvertStr(format(xValue), ',', '.');
            jsValue.ReadFrom(txtValue);
            OrderDetail.Add('totalPrice', jsValue.AsDecimal());
    
            xValue := 1240.00;
            txtValue := DelChr(format(xValue), '=', '.');
            jsValue.ReadFrom(txtValue);
            OrderDetail.Add('quantity', jsValue.AsInteger());
    

    I use two more vars to show what happen, in my case due to regional settings, the decimal point is a comma and in "totalPrice" I need to change after the format so the jsValue.ReadFrom get the correct value.

    In the same way you need to get rid of any thousands separator in both cases.

    Regards.