Code node, struggling compared to the old function node

Hey,

I’m really struggling to get this new code node to work, it just seems like a step backwards in my eyes. Alot more complicated to do simple things, specifically referencing a previous nodes output.

You cant use $input.X.X to reference the bits you need, how we used to do it via $json.x.x

I just don’t seem to be able to reference the things I need, how I used to and the docs are not helping.

Please can someone show me how you do it, $input.all() seems counter intuitive, how do I reference what I need in the all() ?

1 Like

It can be a bit annoying in the beginning, but you will get used to it.
It is actually pretty straightforward.
$input refers to what is coming directly into the node. then you select all, first, last and maybe some more options here.
Then you simply do the .json.field
So you get something like $input.all().json.name
or $input.first().json.name for example.

If you want to get items of a different node you use $(‘nodename’) followed by the same stuff as before.
so for example $(‘Start’).first().json.startField

Hope this makes sense and helps you.

Effectively wherever you used $json, replace it with $input.item.json if you’re using Run Once for Each Item mode. E.g. $json.myfield$input.item.json.myfield

Edit: actually you can still use $json exactly as you have been…

1 Like

ahh,

how about in run once for all items

In run once for all items replace item.myfield with item.json.myfield this is assuming you are looping with…

for (const item of $input.all()) {
// code here
}

wasn’t this already needed for this? :thinking:

I can’t remember, The function node is so early 2022.

1 Like

Nope, this new code node really doesnt want to play nice with me at all.

in “Run once for all items”
const html = $input.first().json.html;
works
const html = $input.all().json.html;
doesnt neither does
const html = $input.all();

also the documentation doesnt help either, i think there is a fundamental lack of examples are troubleshooting on there, it works completely differently to the function nodes and it just seem so much more difficult to get simple things to work. perhaps I’m missing something here, this shouldn’t be that difficult to use… hmmm

Sorry to hear that you have problems. I hope the following makes it clearer.

$input.first() is the first item of the input.
So it is an object with looks roughly like this for your example above:

{
  json: {
    html: '....',
  }
}

$input.all().json.html are all the incoming items and is so an array of objects and looks for your above example like this:

[
  {
    json: {
      html: '....',
    }
  },
  {
    json: {
      html: '....',
    }
  }
]

For that reason does $input.all().json.html not work as you try to access json of an array which is undefined and then you try to access html of undefined.

I hope that helps and makes things clearer! Thanks a lot for bringing this up, will check in with the team regarding improving the docs.

ok so how do i reference in a code node to point to the “xxxx”

[
    {
    "html":"xxxx"
    },
    {
    "html":"xxxx"
     },
     {
     "html":"xxxx"
     }    
]

In the code node I need it to run the script against each incoming item from the previous input.

Which “xxxx” as there are 3 of them?

The first one would be:

$input.all()[0].json.html
// or
$input.first().json.html

The second one:

$input.all()[1].json.html

And the last/third one:

$input.all()[2].json.html
// or
$input.last().json.html

Or you can, for example, combine all of them into one single string with

$input.all().map(item => item.json.html).join(',')

i need to reference them all one by one for the code node to process the values etc bear in mind I don’t know how many there will be as the input

In this case you can use the example that is directly given in the Code-Node when you create a new one.

For “Run Once for All Items” it looks currently like this:

// Loop over input items and add a new field
// called 'myNewField' to the JSON of each one
for (const item of $input.all()) {
  item.json.myNewField = 1;
}

return $input.all();

so for example:

for (const item of $input.all()) {
  item.json.htmlWrapped = `<html>${item.json.html}</html>`;
}

return $input.all();

Or if you change it to “Rune Once for Each Item” the example is this:

// Add a new field called 'myNewField' to the
// JSON of the item
$input.item.json.myNewField = 1;

return $input.item;

so the equivalent to my above example would be:

$input.item.json.htmlWrapped = `<html>${$input.item.json.html}</html>`;

return $input.item;

If I change it to run once for each item

const html = $input.item.json.html;

I get this error:

ERROR: Unknown top-level item key: 0 [item 0]

Access the properties of an item under `.json`, e.g. `item.json`

the input from the node before is:

[
    {
    "html":"html is here already"
    },
    {
    "html":"html is here already"
     },
     {
     "html":"html is here already"
     }    
]

@RedPacketSec I just tried to reproduce your error and think I found your problem. Might it be that you return $input in your code node? The code node in Run once for each item mode expects you to return $input.item.

Here’s a quick workflow that I used to show this:

The error message that you get is very misleading, though. So we will see what we can do there. Thanks for bringing this up :pray:

3 Likes

ok, so that sort of helps, now i need to massage that into my massive script. Thank you that gives me something to work with, much appreciated.

i gave up in the end and bodged it, i really do not like the new code node its 10x more difficult to understand how to wrangle the data.

I just kept it as:

image
and then just split it in batches of 1 so each one will be the first

image

Hi @RedPacketSec I’m also (still) struggling with the new code node. I had this simple FunctionItem that would convert the following with just return item.fieldData

I still haven’t found out how to achieve this in the Code node …

In run once for all items:

// Loop over input items and add a new field
// called 'myNewField' to the JSON of each one
for (const item of $input.all()) {
  item.json = item.json.fieldData;
}

return $input.all();

in Run once for each item:

$input.item.json = $input.item.json.fieldData;

return $input.item;
2 Likes