Simplest way to conditionally Merge outputs from multiple nodes

Describe the issue/error/question

Hello again n8n community! I’m back with more questions about Merge functionality. I’m building a map using location data pulled from multiple (Airtable) tables. I was able to build a workflow using the Merge node and two data sources successfully, but now I would take to add two more tables into the mix and need a different solution because the Merge node only has two inputs.

Additionally, I sometimes have a problem if one of the tables I’m taking data from returns no results, as this inserts an empty item during the merge step and this ends up in my final GEOjson output as empty braces {}, which breaks the map. I need to add some conditional logic to allow the workflow to complete whether data is returned from any 1, or upto all 4 nodes.

I was looking at this workflow example and believe it may be possible to use a function node to merge the data, but without an example showing me how to do this from multiple nodes, the JS is a little beyond me.

Any pointers here would be deeply appreciated.

I’ve shared the workflow below that is working for the top two Airtable list nodes.

What is the error message (if any)?

Please share the workflow

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database you’re using (default: SQLite):
  • Running n8n with the execution process [own(default), main]:
  • Running n8n via [Docker, npm, n8n.cloud, desktop app]:

So I’ve learn that daisy-chaining the Merge node in ‘Append’ mode works quite well. My problem now is that I don’t know how to do this conditionally, since the Merge nodes will ‘pull’ data from connected nodes if an output is not forthcoming. Below is what I’ve got so far:

Hi @Felix_is_stuck, I am not 100% sure I understand your problem after looking at the latest workflow. Is your workflow sometimes not reaching the final Function node?

Or is it always reaching the Function node, but the data doesn’t quite match what you’d like to see? If so, can you confirm which data you currently get from your final Merge node have and what would you like to see instead?

Hi @MutedJam - thank always for you reply!

The function node is working correctly. The problem I have is when one of the Airtable List nodes has got no data to return for the specified query. I force the node to output something [‘Always Output Data’] else the Merge process will fail. This triggers the Set node and inserts an empty entry into the final JSON.

What I need to do is somehow conditionally merge data from the 4 Airtable list nodes, sometimes, only 1 of the nodes will return data, sometimes 2, 3 or all 4. I need some way of aggregating this data into a single JSON output.

Hi @Felix_is_stuck,

If I understand you correctly, then the “merge over (run)index” could help you. Depending on the situation you have to adjust the join option.

I have replaced the airtables with generic functions where one function is completely empty (or produce an error) but “Always Output Data” is set to true and one function outputs more results than the other.

This should cover all situations:

  • No data
  • less data
  • all data

How many merge nodes are used is not important.

If the elements can not be connected over the runIndex, then must be programmed extensively in JavaScript. But then unfortunately I need real data to help.

Translated with DeepL Translate: The world's most accurate translator (free version)

1 Like

Thanks so much for your reply @BillAlex.

Looking into how Merge by Index (Outer Join) works:

Now from the screenshot below, you can see some items have been dropped. I’m. expecting 31 items through ‘Merge1’, but only got 26, and 4 items through ‘Merge’, but only got 3. This makes sense as outer join only passes as many items as the input with the ‘most’ items.

I will gather some dummy data to share to see what else our options might be.

@Felix_is_stuck the items DON’T drop, they merge in one row. If you have an object with attributes like {a: ‘’, b: ‘’} and an other object with {c: ‘’}, after the merge you have {a: ‘’, b: ‘’, c:’’} - same attributes merge by last, I think {a: ‘H’, b:’’} + {a:‘W’,c:’’} => {a:‘W’,b:’’,c:’’}

But I don’t think that’s the problem.

I think I now understand what you are trying to do and where the problem is for you with “Merge: append”.

If an Airtable has no data, but “Always Output Data” is active, you will have a row without content.

To delete such empty rows you need a function like this:

return items.filter(r => {
  return Object.keys(r.json).length > 0
});

This function only works if Airtable-Node give you an empty array [{}].

An example:

If this is not your problem, then we need to clarify what the object should look like that should be stored in AWS S3.

1 Like

Thank you @BillAlex! Yes, this little snipped of code has done the trick. I had to add an IF node after each Set node to stop it from outputting more than the code snippet is looking for “[{}]”, and add your code in an additional function node (I’m sure I could combined the two but not quite sure how).

In case it might help others trying to do something similar, here’s what I ended up with:

1 Like