How to merge two JSON arrays into single object structure using n8n JavaScript

I’m working with an API that provides customer support information across two distinct JSON arrays. I need to merge these arrays into one structured object to use in my workflow.

The first array includes order details:

[
  {
    "order_id": 125,
    "department_id": 1,
    "status_id": 3,
    "client_id": 15,
    "reference_number": "ORD-2024-001",
    "description": "Product inquiry from customer",
    "assigned_to": 7,
    "customer_id": 15,
    "notes": null,
    "created_date": "2024-01-20T09:30:15.123Z",
    "due_date": null,
    "completion_time": 0,
    "processing_minutes": 2880,
    "completed_at": null,
    "category": "inquiry",
    "priority_level": "normal",
    "last_activity": "2024-01-20T10:15:22.456Z",
    "agent_response_at": "2024-01-20T09:45:30.789Z",
    "customer_last_contact": "2024-01-20T10:15:22.456Z",
    "settings": {
      "source_channel": 1,
      "workflow_data": {
        "initial_response": "2024-01-20T09:45:30.789Z",
        "last_modified": "2024-01-20T10:15:22.456Z",
        "auto_close": false
      }
    },
    "modified_by": 7,
    "created_by": 7,
    "created_timestamp": "2024-01-20T09:30:15.100Z",
    "updated_timestamp": "2024-01-20T14:20:10.500Z"
  }
]

The second array contains corresponding messages:

[
  {
    "message_id": 250,
    "order_id": 125,
    "category_id": 2,
    "author_id": 1,
    "sender_email": "john.doe <[email protected]>",
    "recipient": "[email protected]",
    "subject_line": "Product inquiry from customer",
    "thread_id": "<[email protected]>",
    "content": "Hello, I need information about your services.",
    "is_private": false,
    "meta_info": {
      "auto_reply_sent": true,
      "is_automated": false
    },
    "last_edited_by": 7,
    "author_user_id": 7,
    "message_type": "email",
    "sender_role": "Customer",
    "created_timestamp": "2024-01-20T09:45:30.789Z",
    "modified_timestamp": "2024-01-20T09:45:30.789Z"
  }
]

I want to create this combined structure:

{
  "OrderData": {
    "order_id": 125,
    "department_id": 1,
    // ... other order fields
  },
  "Messages": [
    {
      "message_id": 250,
      "order_id": 125,
      // ... other message fields
    }
  ]
}

I’m seeking assistance in writing the JavaScript code for n8n that can merge these arrays and assigns the appropriate field names. I’m not well-versed in JavaScript, so I could use some guidance on how to structure this merge operation.

Quick tip - check for empty arrays first or you’ll get errors. Use if (orderArray && orderArray.length > 0) before hitting orderArray[0]. Your API might return multiple orders too, so consider orderArray.map() to handle batches properly.

I hit the same issue when building workflows that pull from multiple endpoints. You’re basically restructuring data, not just merging arrays.

Here’s the JavaScript for your n8n function node:

const orderArray = $input.first().json.orderData; // adjust path as needed
const messageArray = $input.first().json.messageData; // adjust path as needed

const result = {
  OrderData: orderArray[0], // assumes single order
  Messages: messageArray.filter(msg => msg.order_id === orderArray[0].order_id)
};

return [{ json: result }];

Make sure your input data paths match what n8n’s actually sending. I always throw in a console.log or check the browser inspector to see the exact structure from your API calls before writing the merge logic.

For multiple orders, loop through the order array and create separate objects for each one with its messages. The filter method grabs only messages that belong to each specific order.

n8n’s data structure can be tricky when you’re merging arrays from different nodes. Here’s how I handle it:

const orders = $input.all()[0].json; // first node output
const messages = $input.all()[1].json; // second node output

const mergedData = orders.map(order => {
  const relatedMessages = messages.filter(msg => msg.order_id === order.order_id);
  
  return {
    OrderData: order,
    Messages: relatedMessages
  };
});

return mergedData.map(item => ({ json: item }));

This grabs multiple orders and matches messages by order_id. The main thing here is using $input.all() to pull data from multiple nodes instead of just one input. Don’t forget to wrap your output with the json property - n8n expects that format.