How to transform json data iterating over nested objects

Describe the problem/error/question

Hello n8n community. I have an issue trying to transform input json format to a different output json format.

I’m working with Shopify orders API and I need to iterate over “line_items” nested object for each order to create a specific json output format.

Json input sample (2 order items. First order contains 3 line_items (products), record order contains 2 line_items (products)

[
  {
    "id": 5748868579666,
    "checkout_id": 42532585144658,
    "contact_email": "[email protected]",
    "created_at": "2023-10-11T16:44:36+02:00",
    "currency": "EUR",
    "gateway": "shopify_payments",
    "order_number": 30856,
    "total_price": "142.95",
    "line_items": [
      {
        "id": 14842885341522,
        "name": "Product Name Sample 1",
        "price": "114.95",
        "product_exists": false,
        "product_id": null,
        "quantity": 1,
        "requires_shipping": true,
        "sku": null,
        "taxable": true,
        "total_discount": "0.00",
        "variant_id": null,
        "variant_inventory_management": null,
        "variant_title": null,
        "vendor": ""
      },
      {
        "id": 14842885374290,
        "name": "Product Name Sample 2",
        "price": "14.00",
        "product_exists": false,
        "product_id": null,
        "quantity": 2,
        "requires_shipping": true,
        "sku": null,
        "taxable": true,
        "variant_id": null,
        "variant_inventory_management": null,
        "variant_title": null,
        "vendor": ""
      },
      {
        "id": 14842885407058,
        "name": "Product Name Sample 3",
        "price": "0.00",
        "product_exists": false,
        "product_id": null,
        "quantity": 1,
        "requires_shipping": true,
        "sku": null,
        "taxable": true,
        "variant_id": null,
        "variant_inventory_management": null,
        "variant_title": null,
        "vendor": ""
      }
    ]
  },
  {
    "id": 5748910817618,
    "checkout_id": 42532794990930,
    "contact_email": "[email protected]",
    "created_at": "2023-10-11T17:17:39+02:00",
    "currency": "EUR",
    "gateway": "shopify_payments",
    "order_number": 30857,
    "total_price": "93.95",
    "line_items": [
      {
        "id": 14842985054546,
        "name": "Product Name Sample 3",
        "price": "14.00",
        "product_exists": true,
        "product_id": 8233889497361,
        "quantity": 1,
        "requires_shipping": true,
        "sku": "ADF201",
        "taxable": true,
        "total_discount": "0.00",
        "variant_id": 46484656226642,
        "variant_inventory_management": null,
        "variant_title": "14€ Pr",
        "vendor": "floral s"
      },
      {
        "id": 14842985087314,
        "name": "PRoduct name sample 4",
        "price": "84.95",
        "product_exists": true,
        "product_id": 6649794265174,
        "quantity": 1,
        "requires_shipping": true,
        "sku": "PP147",
        "taxable": true,
        "total_discount": "0.00",
        "variant_id": 39585167474774,
        "variant_inventory_management": null,
        "variant_title": null,
        "vendor": "A bcn"
      }
    ]
  }
]

JSON Output format I would need to have is (but with all the products (not only the fist one for each order)

So, the question is, how can I iterate over line_items object?
I used a Set node to try to do that. Is it possible with a Set node? If not, how the code node should looks like to iterate and get the output json desired?

[
  {
    "cartId": 42532585144658,
    "contactEmail": "[email protected]",
    "paymentMethod": "shopify_payments",
    "purchaseId": 30856,
    "purchaseDate": "2023-10-11T16:44:36+02:00",
    "totalPrice": 142.95,
    "products": [
      {
        "productId": 14842885341522,
        "name": "Product Name Sample 1",
        "unitPrice": 114.95,
        "quantity": 1,
        "price": "price * quantity. How to?"
      }
    ]
  },
  {
    "cartId": 42532794990930,
    "contactEmail": "[email protected]",
    "paymentMethod": "shopify_payments",
    "purchaseId": 30857,
    "purchaseDate": "2023-10-11T17:17:39+02:00",
    "totalPrice": 93.95,
    "products": [
      {
        "productId": 14842985054546,
        "name": "Product Name Sample 3",
        "unitPrice": 14,
        "quantity": 1,
        "price": "price * quantity. How to?"
      }
    ]
  }
]

Workflow sample:

THANKS

Information on your n8n setup

  • n8n version: 1.8.2
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Hi @Alex_Camara, welcome to the community!

On later versions of n8n you can actually iterate over each of your line_items using arrow functions inside the Set node. This is because @Val from our engineering team worked really hard on writing a new library to evaluate expressions which was introduced with n8n 1.9.0.

On previous versions you can still avoid using the Code node, but would need a bit more than just the Set node. Here’s a quick example workflow built on your n8n version n8n 1.8.2. It’ll first create individual batches for each of your incoming items using the Split In Batches node, then splitting out the line_items before finally using the Set node to create your example data structure for the products field. A second Set node will then create the overall data structure following the loop.

This is the result:

Hope this helps! Let me know if you have any questions on this example workflow :slight_smile:

Hi @MutedJam , nice to meet you and thanks a lot for your answer.

I got a similar conclusion but with some errors that prevented me to end close the workflow and this is helping a lot.

I have a follow-up question and it’s regarding how you instance a previous node data.
You are using something like:
{{ $(‘Split In Batches’).first().json.checkout_id }}

The question is why do you use “.first().” instead of “.item.” (that is the usual expression n8n is adding by default when drag-and-drop items in the Expression box)

Apart from that, I have a secondary problem I’m trying to solve without success even I tested many options.
In my output json payload, I need to include a key-value that is the sum of line_items quantity.

totalQuantity”: "The quantity of products purchased. This should match the addition of all individual product quantities. Sum of line_items.[i].quantity ".

I used a summarize: ItemList node for that purpose after the splitOutItems, the issue is how to merge everything (in the same json Payload):

  • split in batches node data
  • items sum
  • Products (array)

Here an example of what I’m doing without success.
The output that I’m getting is a 2 items json, when it should be only one (one of them including Products array and the other no).

Note: I reduced the initial json payload to only 1 order in order to simplify errors

Workflow:

Thanks a lot for your support.

Alex

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.