How to reference previous node's data, manipulate string

Hi all,

NOTE: This seems a basic issue to me, but I did search for a solution to no avail. If an answer to this already exists, please kindly point me there - thank you!

I have json data received by a webhook node. One data in the json is a URL. The URL contains an ID that I want to extract (substr() ?) and pass to the next node.

My challenge is two-faced:

  1. In the Functions node, I cannot figure out how to reference data from a previous node, although I otherwise built the JS function I need.
  2. In the Expression feature, I cannot figure out how to perform JS functions, although I do know how to reference previous node data there.

If I can solve either of these challenges, I think I will have my solution.

I understand automation and workflows and I have an average understanding of JS. Connecting JS with n8n is still unknown territory for me. Please help :slightly_smiling_face:

EP

EDIT Solution: I was trying to return a string from JS function but needed to return json. Also, the FunctionItem node was more useful in this case, and referencing previous nodes follows this pattern: $node[ā€œName of Source Nodeā€].json[ā€œName of Dataā€]

Hi @Entrepositive, welcome to the community!

In the Function node you can read the incoming data via items. You can also use other expressions such as $items() which allow you to pick which node you want to read data from. Check out our documentation on these expressions: Methods - n8n Documentation

Iā€™ve also attached a small workflow below showing you how to read data from other nodes in the Function node:

As for using JS inside an expression, this is a bit limited because of the underlying library. Basic stuff should however work, for example:

Hope this helps! Give me a shout if you have any questions on this.

1 Like

Donā€™t forget about the function Item node. :wink:

Just a function node but then easier to use if you want to run it for each item in your workflow. :slight_smile:
No need to keep in mind the json structure with this one. :slight_smile:

1 Like

Hi @MutedJam thanks for your detailed reply.

Hereā€™s an example Workflow of what Iā€™m trying. Iā€™m not sure if this will workā€¦

Thanks @BramKn

I did try the FunctionItem Node but my use case doesnā€™t involve iterating through a data set, rather just extracting one string from a URL (substring from a string).

I think this is an issue of me learning how to use n8n for this use case, but unfortunately the docs are not yet detailed and tutorials are difficult to findā€¦

EP

Hi @Entrepositive

The expression editor should do the trick for that. :wink:

and if you cannot get that to work the function Item node should do the trick without needing to worry about the structure of an item. (so pretty much how you have your function set up now can be pasted in function item)

1 Like

Hey Bram,

Iā€™m not trying to be disrespectful I just donā€™t know what Iā€™m doing here. None of these nodes ā€œdo the trickā€ because Iā€™m not using them correctly.

If someone can show me how I can implement the following script to extract a piece of a string, that would be extremely helpful. And then I can extrapolate the knowledge into other areas and use cases.

const myURL = $node[ā€œWebhook dataā€].json[ā€˜Attachment URLā€™];
const attachmentID = myURL.substr( myURL.indexOf(ā€œattachments/ā€)+12, 24 )
return attachmentID;

I have searched this forum, I have scoured the docs, and Iā€™ve spent time in YouTube videos. Iā€™m here because I didnā€™t find any good introductory tutorial that shows how to correctly implement JS in n8n.

The bottom of this page suggests it is not possible to use advanced Javascript in the Expression feature.

Thanks, and I hope this makes sense.

EP

What I essentially need is to pull that part of the data out of this URL. I would be open to any solution.

Thanks,

EP

Have you tried the Function Item node suggested by @BramKn further up? Thatā€™s a bit simpler than the Function node as it only looks at your current item.

If you have data like this:

You could connect the node returning this data to a Function Item (not Function) node running a snippet like this:

const myURL = item["Attachment URL"];
const attachmentID = myURL.substr( myURL.indexOf("attachments/")+12, 24 );
return {
  myId: attachmentID
};

In a workflow this would look like so:

PS

That said, the example data from your Webhook node screenshot looks very unusual - did you perhaps manually overwrite it? If so, you might need to adjust the code accordingly to reference your real-world data. For example, if your data is sent through under body like below, the first line of the code would have to be const myURL = item.body["Attachment URL"];

1 Like

@MutedJam that worked! Thank you!

I think the critical part missing from my code was returning a json, rather than a string:

return {
  myId: attachmentID
};

Now the bonus roundā€¦ How do I reference that node as in this line:

const myURL = item[ā€œAttachment URLā€];

if it is not immediately following the source node?

For example:

Source Node > Other Node > IF > Function Item Node (that accesses Source Node data)

Thanks,

EP

1 Like

There are lot of different ways. Iā€™d usually suggest using a Merge node in pass through mode to get whatever data you need, but as for the code route hereā€™s an example:

Replace Mock Data in the Function Item code with the name of the node you want to retrieve your item from.

1 Like

I just noticed your PS @MutedJam. That does make sense; I did simplify to static data for this example. I will keep this in mind.

So if I need to reference data within json within item:

{
 person {
  name: "Pete",
  age: 50
 },
 pet {
  name: "Rufus",
  type: "Dog"
 }
}

I would reference like: item.person.name[ā€œPeteā€] ?

I would reference like: item.person.name[ā€œPeteā€] ?

Almost. Pete is your value in this example data structure. So youā€™d only need to reference item.person.name to read this value.

1 Like

This makes sense!

I think thatā€™s how I originally had mine structured earlier, but perhaps in a Function node, and not Function Item. And in any case I was trying to return a string outside of json.

I suppose the JS in a node must always return jsonā€¦or?

Hopefully some other newbs like me will get some value out of this. Thanks a lot @MutedJam and @BramKn - big help today!

EP

1 Like

Yep, n8n requires a specific JSON data structure. The Function Item node abstracts quite a bit of it, but if youā€™re curious, hereā€™s Harshil explaining the basic concept:

This is also documented at Data structure - n8n Documentation

2 Likes

This is a helpful vid - thank you for sharing this.

Also I want to add one small detail thatā€™s probably a non-issue to most but still tripped me up for a sec:

After building code (correctly) in the FunctionItem node, the node itself needs to be executed once before the returned result can be accessed further down the workflow. Attempting to reference that FunctionItem nodeā€™s data before it was executed will pull the raw JS code, rather than just the returned json. Obviously this is not what we want, so execute it once.

Hope that helps.

EP

1 Like

No worries @Entrepositive

And that the index does not work in the expression editor didnā€™t work, I did not know.
Iā€™ve now had the chance to actually check what you were doing and got a way to use it in the expression editor by using split and slice.
So that is still an option if you want it. :slight_smile:
Happy to have helped, although @MutedJam did most of the heavy lifting :sweat_smile:

ps. if you simply want to add the value to the item object you can also do:

item.myId = attachmentID;
return item;
1 Like

@BramKn hey cool!

={{$node[ā€œMock Dataā€].json[ā€œAttachment URLā€].split(ā€˜attachments/ā€™)[1].slice(0,24)}}

This is all very helpful!

EP

2 Likes