# \[behavior\] Activating a function from the previous function node

**URL:** <https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168>\
**Category:** General\
**Created:** [25 March 2021 07:51 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168 "2021-03-25T07:51:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nxito](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nxito/32/88293_2.png) [@Nxito](https://discourse.nodered.org/u/Nxito)\
**Post date:** [25 March 2021 07:51 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/1 "2021-03-25T07:51:53Z")

</div>

I was testing something, and i see this behavior with node functions and the node-red.

I have created two function nodes:  
-the first one creates a function with node.send ()  
-the second calls this function  
-I get an error, but the function is performed in the previous node

```auto
[{"id":"3cd6fd57.dbf502","type":"inject","z":"444df3bd.bed4dc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":140,"wires":[["f740d75f.c6de88"]]},{"id":"f740d75f.c6de88","type":"function","z":"444df3bd.bed4dc","name":"set function in msg","func":"msg.functions={\n foo:function(){\n node.send({\"test\":\"test\"})\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":290,"y":140,"wires":[["d19ea6d5.e69e48","8deb8124.fb84b"]]},{"id":"513f0336.015a8c","type":"debug","z":"444df3bd.bed4dc","name":"out 1 :D","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":720,"y":140,"wires":[]},{"id":"d19ea6d5.e69e48","type":"function","z":"444df3bd.bed4dc","name":"apply func","func":"msg.functions.foo()\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":510,"y":140,"wires":[["513f0336.015a8c"]]},{"id":"8deb8124.fb84b","type":"debug","z":"444df3bd.bed4dc","name":"Why im here?","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":520,"y":200,"wires":[]}]

```

I am doing something wrong?  
why does this behave like this?

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/c/fc8e9e648bc48de0a78a4a07dcd4d325a1860f32.png)  
This is not a big problem, it is just that I do not understand the behavior

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [25 March 2021 07:57 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/2 "2021-03-25T07:57:13Z")

</div>

What happens is it works - then the 1st functions `.foo()` method _node.sends_ a message containing only `{"test":"test"}` to the 2nd function (which does not contain `.functions`) - hence the error. If you test for the presence of `msg.functions` in your 2nd function it wont happen.

Add `node.warn(["msg in function 1", msg])` and `node.warn(["msg in function 2", msg])` to your functions this should be clearer

---

<div class="post-metadata">

**Author:** ![Nxito](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nxito/32/88293_2.png) [@Nxito](https://discourse.nodered.org/u/Nxito)\
**Post date:** [25 March 2021 08:24 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/3 "2021-03-25T08:24:09Z")

</div>

ok, I understood why this gave me an error.  
The behavior that I thought this would have is that when activating the function in the second node, it would act on the second, not the first.  
or so I think  
it may help me for some recursive tasks ,since I could loop with this

```auto
[{"id":"3cd6fd57.dbf502","type":"inject","z":"444df3bd.bed4dc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":680,"y":120,"wires":[["f740d75f.c6de88"]]},{"id":"f740d75f.c6de88","type":"function","z":"444df3bd.bed4dc","name":"set function in msg","func":"msg.functions={\n foo:function(){ \n node.send({\n \"test\":\"test\",\n functions:{\n foo:function(){\n node.warn(\"end\")\n }\n }\n })\n }\n}\nnode.warn([\"msg in function 1\", msg])\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":860,"y":120,"wires":[["d19ea6d5.e69e48","8deb8124.fb84b"]]},{"id":"513f0336.015a8c","type":"debug","z":"444df3bd.bed4dc","name":"out 1 :D","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1290,"y":120,"wires":[]},{"id":"d19ea6d5.e69e48","type":"function","z":"444df3bd.bed4dc","name":"apply func","func":"node.warn([\"msg in function 2\", msg])\nmsg.functions.foo()\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1080,"y":120,"wires":[["513f0336.015a8c"]]},{"id":"8deb8124.fb84b","type":"debug","z":"444df3bd.bed4dc","name":"Why im here?","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1090,"y":180,"wires":[]}]

```

thanks for answering

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [25 March 2021 08:37 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/4 "2021-03-25T08:37:54Z")

</div>

> [@Nxito](#):
>
> The behavior that I thought this would have is that when activating the function in the second node, it would act on the second, not the first.

No, a function operates where you design it unless you pass in some context to operate on.

There are a few ways (binding / apply etc) but here are 2 of the simpler ways...

First one - you pass in the node context to operate on...

```auto
// function 1
msg.functions={
    foo:function(n){
        n.send({"desc":"foo"})
    },
    bar:function(n){ 
        n.send({"desc":"bar"})
    }
}

// function 2
msg.functions.foo(node)
msg.functions.bar(node)

```

Another way is a function factory...

```auto
// function 1
msg.functionFactory=function(_node){
    var node = _node;
    return {
        foo:function(){ node.send({"desc":"foo"}) },
        bar:function(){ node.send({"desc":"bar"}) }
    }
}

// function 2
var ff = new msg.functionFactory(node);
ff.foo()
ff.bar()

```

demo flow...

```auto
[{"id":"3cd6fd57.dbf502","type":"inject","z":"336fad55.d74c02","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":844,"y":544,"wires":[["f740d75f.c6de88"]]},{"id":"f740d75f.c6de88","type":"function","z":"336fad55.d74c02","name":"passing context","func":"msg.functions={\n foo:function(n){\n n.send({\"desc\":\"foo\"})\n },\n bar:function(n){ \n n.send({\"desc\":\"bar\"})\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1014,"y":544,"wires":[["d19ea6d5.e69e48","8deb8124.fb84b"]]},{"id":"513f0336.015a8c","type":"debug","z":"336fad55.d74c02","name":"out 1 :D","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1454,"y":544,"wires":[]},{"id":"d19ea6d5.e69e48","type":"function","z":"336fad55.d74c02","name":"apply func","func":"msg.functions.foo(node)\nmsg.functions.bar(node)\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1244,"y":544,"wires":[["513f0336.015a8c"]]},{"id":"8deb8124.fb84b","type":"debug","z":"336fad55.d74c02","name":"Why im here?","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1254,"y":604,"wires":[]},{"id":"f7bdf46e.066cb8","type":"inject","z":"336fad55.d74c02","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":844,"y":656,"wires":[["2fb421b0.9c836e"]]},{"id":"2fb421b0.9c836e","type":"function","z":"336fad55.d74c02","name":"functionFactory","func":"msg.functionFactory=function(_node){\n var node = _node;\n return {\n foo:function(){ node.send({\"desc\":\"foo\"}) },\n bar:function(){ node.send({\"desc\":\"bar\"}) }\n }\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1014,"y":656,"wires":[["ceed402d.fb068","dfe7dc7d.9db2e"]]},{"id":"ceed402d.fb068","type":"function","z":"336fad55.d74c02","name":"apply func","func":"var ff = new msg.functionFactory(node);\nff.foo()\nff.bar()","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1244,"y":656,"wires":[["a763a36d.2b0b7"]]},{"id":"dfe7dc7d.9db2e","type":"debug","z":"336fad55.d74c02","name":"Why im here?","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1254,"y":716,"wires":[]},{"id":"a763a36d.2b0b7","type":"debug","z":"336fad55.d74c02","name":"out 1 :D","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1454,"y":656,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [25 March 2021 09:17 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/5 "2021-03-25T09:17:21Z")

</div>

This will be fine most of the time - at some point in the future if you start to use messaging plugins this may not work as functions are not generally serialisable.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [25 March 2021 09:19 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/6 "2021-03-25T09:19:48Z")

</div>

@Nxito - what Dave said 🙂 (I neglected to include the caveat).

The better way (for now) would probably be to include your functions via settings.js

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [25 March 2021 09:23 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/7 "2021-03-25T09:23:28Z")

</div>

well - it's only a small caveat and unlikely for most users - but do remember it if it stops working in the future for some "random" reason.

---

<div class="post-metadata">

**Author:** ![Nxito](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nxito/32/88293_2.png) [@Nxito](https://discourse.nodered.org/u/Nxito)\
**Post date:** [25 March 2021 09:31 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/8 "2021-03-25T09:31:47Z")

</div>

Thank you very much for the warning, I will keep it in mind 😄

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [8 April 2021 09:32 UTC](https://discourse.nodered.org/t/behavior-activating-a-function-from-the-previous-function-node/43168/9 "2021-04-08T09:32:37Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
