JavaScript nested array parsing issue in n8n workflow automation

I’m working with n8n automation and getting stuck on a JavaScript problem. My workflow pulls data from an API that returns complex nested arrays, but I can’t get the deep nested parts to display properly.

Here’s what my incoming data structure looks like:

{
  "status": "ok",
  "posts": [
    {
      "id": "xyz789",
      "headline": "example content goes here",
      "description": "more example content here",
      "category": "private",
      "createdAt": "2022-03-15T09:30:00.000+00:00",
      "url": "https://example_url_here",
      "topics": [],
      "keywords": [
        "word1",
        "word2", 
        "word3",
        "word4"
      ],
      "metrics": [
        {
          "name": "example metric type",
          "total": 7,
          "items": [
            "item one",
            "item two",
            "item three"
          ],
          "origin": "internal"
        }
      ]
    }
  ]
}

My n8n function node code looks like this:

const output = []
for (const record of items) {
  output.push.apply(output, record.json.posts)
}

return output.map(item => {
  const result = {};
  for (const field of Object.keys(item)) {
    if (field === 'keywords') {
      result[field] = item[field].toString().replace(/,/g, '\n');
      continue;
    }
    if (field === 'metrics') {
      result[field] = item[field].map(entry => entry.title).toString().replace(/,/g, '\n');
      continue;
    }
    result[field] = typeof item[field] === 'object' ? JSON.stringify(item[field]) : item[field];
  }
  return { json: result };
})

The problem is my metrics field comes out empty in the final output. The keywords work fine but the deeper nested metrics array doesn’t process correctly. When I export this to Google Sheets, the metrics column is blank.

How do I fix the JavaScript to handle these multi-level nested arrays properly? I’m not great with JavaScript so any help would be appreciated.

Had this exact issue with n8n pulling from nested API responses. The entry.title vs entry.name thing others mentioned is right on, but there’s another problem - your code assumes metrics always exists and is always an array. APIs sometimes return null or empty objects which breaks everything.

Add a safety check before processing:

if (field === 'metrics' && Array.isArray(item[field]) && item[field].length > 0) {
  result[field] = item[field].map(entry => entry.name).toString().replace(/,/g, '\n');
  continue;
}

Watch out for toString() too - if metric names have special characters or are null, it’ll mess up your Google Sheets output. Been burned by this with client data imports. Adding null checks saved me hours of debugging when the API started returning incomplete data.

The property name mismatch isn’t your only problem. Your metrics processing grabs just the name field and tosses everything else - total and items included. You’re throwing away valuable data.

For better Google Sheets output, flatten the whole metrics object:

if (field === 'metrics') {
  result[field] = item[field].map(entry => `${entry.name}: ${entry.total} (${entry.items.join(', ')})`).join('\n');
  continue;
}

This way you get the complete picture. I’ve seen similar n8n setups where partial extraction creates problems later. One more thing - your code assumes metrics is always an array. Add validation so you don’t crash when the API changes.

The answers above fix the technical issue, but you’ve got a bigger problem - maintenance. Every API change means more JavaScript debugging.

I’ve hit this exact wall multiple times. Started with n8n for data transformations, then wasted tons of time fixing parsing issues whenever APIs changed.

Latenode handles nested arrays way better. Instead of custom JavaScript for each structure, you get visual mapping that auto-detects nested fields. When I switched similar workflows, nested array processing became simple drag-and-drop.

The real payoff comes when your API adds fields or changes structure. With Latenode, you just remap visually instead of rewriting code. The Google Sheets integration also handles complex nested formatting automatically.

For now, yeah - change entry.title to entry.name like everyone said. But long-term, consider switching to something that’s easier to maintain.

Check out the visual data transformation features: https://latenode.com

Found your problem. You’re trying to access entry.title but your metrics objects use name, not title. That’s why you’re getting nothing.

Change this:

result[field] = item[field].map(entry => entry.title).toString().replace(/,/g, '\n');

To this:

result[field] = item[field].map(entry => entry.name).toString().replace(/,/g, '\n');

Hit this same thing with n8n API responses before. Property names rarely match what you expect, especially with third-party APIs. Always check the actual field names first. Pro tip: throw in some console logging - just log item[field] before processing so you can see what properties you’re actually working with.

quick debugging tip - throw a console.log(item[field]) right before you process the metrics to see what’s actually in there. I bet you’ll catch more property mismatches that way. also, wrap it in try-catch since nested arrays get weird with API responses.