# Example: Constructing JSON

**URL:** <https://community.easymorph.com/t/example-constructing-json/1279>\
**Category:** General Q&A\
**Created:** [September 9, 2019, 10:56am UTC](https://community.easymorph.com/t/example-constructing-json/1279 "2019-09-09T10:56:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 9, 2019, 10:56am UTC](https://community.easymorph.com/t/example-constructing-json/1279/1 "2019-09-09T10:56:29Z")

</div>

Moved from [Parsing JSON/XML from web responses](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/7)

---

<div class="post-metadata">

**Author:** ![adambeltz](https://community.easymorph.com/user_avatar/community.easymorph.com/adambeltz/32/3678_2.png) [@adambeltz](https://community.easymorph.com/u/adambeltz)\
**Post date:** [September 9, 2019, 2:44am UTC](https://community.easymorph.com/t/example-constructing-json/1279/2 "2019-09-09T02:44:27Z")

</div>

Hey @dgudkov -  
Related but perhaps off topic.

I just wanted to open this up to see if others have a tough time with this. I struggle with "Constructing" the JSON files more than anything, especially when it has depth to it. Here is an example:

Again, I've been recently working on Magento so I'll keep it relevant to that:  
[https://devdocs.magento.com/swagger/#/salesInvoiceRepositoryV1/salesInvoiceRepositoryV1SavePost](https://devdocs.magento.com/swagger/#/salesInvoiceRepositoryV1/salesInvoiceRepositoryV1SavePost)

In this example if you want to invoice the customer you need to define the product(s) and their qty's in  
POST /V1/invoices/

So the post is potentially different between each sales order based on the number of lines the sales order has. In this case the business user & ERP know that this order has (3) lines and its fully invoiced, but the next order only has (2) lines so if we know that information in a flat file, constructing it in JSON to me is a bit tricky.

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 9, 2019, 10:56am UTC](https://community.easymorph.com/t/example-constructing-json/1279/4 "2019-09-09T10:56:29Z")

</div>

Constructing a JSON is easier than parsing. I've created a reusable module that converts any table (single-line or multi-line) into a valid JSON. With this module, constructing a JSON for the Magento endpoint you mentioned is a breeze. See below:

[construct-json.morph](https://community.easymorph.com/uploads/short-url/m063pNiVTAgev8a7h7z93mlXbAU.morph) (13.6 KB)  
[JSON\_data.xlsx](https://community.easymorph.com/uploads/short-url/tW23yTxyBBdtJuqOhGUn8QY2w3f.xlsx) (11.8 KB)

**Module: Main**  
In this module we start creating child JSON elements first. And then we simply append them into the parent JSON as columns. `Table2json` recognizes when a column value is a JSON element or JSON array, and treats it accordingly. Repeat as many times as many child-parent relationships are in the desired JSON.

The final dataset is converted into JSON again.

 ![image](https://community.easymorph.com/uploads/default/original/2X/4/4c49f1b74ba5b4e331326e67f871553bc0369528.png)

**Module: Table2json**  
The module has 2 modes:

- Single-line tables are converted into a single JSON element, e.g. `{"Column1":100}`.
- Multi-line tables are converted into a JSON array, e.g. `[{"Column1":100}, {"Column1":200}]`

EasyMorph data types are converted into JSON notation:

```
Text -> "Text"
Number -> 1234.34
Boolean -> true / false
Empty -> null

```

If a column value is already a JSON element or JSON array it remains as is. This allows nesting child JSON elements/arrays into a parent JSON element.

The input table must not have a column named "RowNo".

When the module is opened first time, the "Input" action is empty. To populate it with data, right-click the action with desired output dataset, and choose "Send to Clipboard". See here: [Simplest way to copy data from datagrid to paste in input action](https://community.easymorph.com/t/simplest-way-to-copy-data-from-datagrid-to-paste-in-input-action/1251)

 ![image](https://community.easymorph.com/uploads/default/original/2X/1/1352c2ac9256a2529d30cb80b37965ac35d789f4.png)

The result is a valid JSON that passes RFC 4627 validation in an online JSON formatter.

```auto
{
   "entity":{
      "extension_attributes":{
         "gw_tax_amount":"string",
         "gw_price":"string",
         "gw_items_tax_amount":"string",
         "gw_items_price":"string",
         "gw_items_base_tax_amount":"string",
         "gw_items_base_price":"string",
         "gw_card_tax_amount":"string",
         "gw_card_price":"string",
         "gw_card_base_tax_amount":"string",
         "gw_card_base_price":"string",
         "gw_base_tax_amount":"string",
         "gw_base_price":"string",
         "gift_cards_amount":0,
         "customer_balance_amount":0,
         "base_gift_cards_amount":0,
         "base_customer_balance_amount":0
      },
      "comments":[
         {
            "comment":"string",
            "created_at":"string",
            "entity_id":0,
            "extension_attributes":{

            },
            "is_customer_notified":0,
            "is_visible_on_front":0,
            "parent_id":0
         },
         {
            "comment":"string",
            "created_at":"string",
            "entity_id":1,
            "extension_attributes":{

            },
            "is_customer_notified":0,
            "is_visible_on_front":0,
            "parent_id":0
         }
      ],
      "items":[
         {
            "additional_data":"string",
            "base_cost":0,
            "base_discount_amount":0,
            "base_discount_tax_compensation_amount":0,
            "base_price":0,
            "base_price_incl_tax":0,
            "base_row_total":0,
            "base_row_total_incl_tax":0,
            "base_tax_amount":0,
            "description":"string",
            "discount_amount":0,
            "discount_tax_compensation_amount":0,
            "entity_id":1,
            "extension_attributes":{

            },
            "name":"string",
            "order_item_id":0,
            "parent_id":0,
            "price":0,
            "price_incl_tax":0,
            "product_id":0,
            "qty":0,
            "row_total":0,
            "row_total_incl_tax":0,
            "sku":"string",
            "tax_amount":0
         },
         {
            "additional_data":"string",
            "base_cost":0,
            "base_discount_amount":0,
            "base_discount_tax_compensation_amount":0,
            "base_price":0,
            "base_price_incl_tax":0,
            "base_row_total":0,
            "base_row_total_incl_tax":0,
            "base_tax_amount":0,
            "description":"string",
            "discount_amount":0,
            "discount_tax_compensation_amount":0,
            "entity_id":0,
            "extension_attributes":{

            },
            "name":"string",
            "order_item_id":0,
            "parent_id":0,
            "price":0,
            "price_incl_tax":0,
            "product_id":0,
            "qty":0,
            "row_total":0,
            "row_total_incl_tax":0,
            "sku":"string",
            "tax_amount":0
         }
      ],
      "updated_at":"string",
      "transaction_id":"string",
      "total_qty":0,
      "tax_amount":0,
      "subtotal_incl_tax":0,
      "subtotal":0,
      "store_to_order_rate":0,
      "store_to_base_rate":0,
      "store_id":0,
      "store_currency_code":"string",
      "state":0,
      "shipping_tax_amount":0,
      "shipping_incl_tax":0,
      "shipping_discount_tax_compensation_amount":0,
      "shipping_amount":0,
      "shipping_address_id":0,
      "order_id":0,
      "order_currency_code":"string",
      "is_used_for_refund":0,
      "increment_id":"string",
      "grand_total":0,
      "global_currency_code":"string",
      "entity_id":0,
      "email_sent":0,
      "discount_tax_compensation_amount":0,
      "discount_description":"string",
      "discount_amount":0,
      "created_at":"string",
      "can_void_flag":0,
      "billing_address_id":0,
      "base_total_refunded":0,
      "base_to_order_rate":0,
      "base_to_global_rate":0,
      "base_tax_amount":0,
      "base_subtotal_incl_tax":0,
      "base_subtotal":0,
      "base_shipping_tax_amount":0,
      "base_shipping_incl_tax":0,
      "base_shipping_discount_tax_compensation_amnt":0,
      "base_shipping_amount":0,
      "base_grand_total":0,
      "base_discount_tax_compensation_amount":0,
      "base_discount_amount":0,
      "base_currency_code":"string"
   }
}

```

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [October 10, 2019, 9:02pm UTC](https://community.easymorph.com/t/example-constructing-json/1279/5 "2019-10-10T21:02:45Z")

</div>

\*\*\*\*\* moved from #Beta lounge to #General Q&A

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [December 7, 2019, 10:35am UTC](https://community.easymorph.com/t/example-constructing-json/1279/6 "2019-12-07T10:35:24Z")

</div>

Here is an updated example that uses the ["Construct JSON"](http://help.easymorph.com/doku.php?id=transformations:constructjson) action that became available starting from version 4.1. It's simpler because it doesn't require a separate module.

[construct-json.morph](https://community.easymorph.com/uploads/short-url/qlhc3zdusCyuxWf2u0h0dqvgo0v.morph) (13.1 KB)

 ![image](https://community.easymorph.com/uploads/default/original/2X/a/a38c5682ce2c6e2ce6e5aa81a1749a80638f189f.png)
