From d84c2b780bc2232728b1230638c1ccf01cf63c11 Mon Sep 17 00:00:00 2001 From: Melvin Groenhoff Date: Fri, 4 Sep 2020 10:20:30 +0200 Subject: [PATCH] Fix `this` context when calling multiple event listeners (fixes #2692). --- .../@node-red/runtime/lib/nodes/Node.js | 3 +- .../@node-red/runtime/lib/nodes/Node_spec.js | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/Node.js b/packages/node_modules/@node-red/runtime/lib/nodes/Node.js index a834c8c34..c227ef2b4 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/Node.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/Node.js @@ -214,7 +214,8 @@ Node.prototype._emitInput = function(arg) { c++; } try { - node._inputCallbacks[i]( + cb.call( + node, arg, function() { node.send.apply(node,arguments) }, function(err) { diff --git a/test/unit/@node-red/runtime/lib/nodes/Node_spec.js b/test/unit/@node-red/runtime/lib/nodes/Node_spec.js index 1f9ca04ce..f8d6c24f8 100644 --- a/test/unit/@node-red/runtime/lib/nodes/Node_spec.js +++ b/test/unit/@node-red/runtime/lib/nodes/Node_spec.js @@ -216,6 +216,7 @@ describe('Node', function() { n2.on('input',function(msg) { // msg equals message, and is not a new copy messageReceived = true; + should.strictEqual(this,n2); should.deepEqual(msg,message); should.strictEqual(msg,message); done(); @@ -224,6 +225,34 @@ describe('Node', function() { messageReceived.should.be.false(); }); + it('emits a single message - multiple input event listeners', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + var message = {payload:"hello world"}; + var messageReceived = 0; + n2.on('input',function(msg) { + // msg equals message, and is not a new copy + messageReceived++; + messageReceived.should.be.exactly(1); + should.strictEqual(this,n2); + should.deepEqual(msg,message); + should.strictEqual(msg,message); + }); + n2.on('input',function() { + messageReceived++; + messageReceived.should.be.exactly(2); + should.strictEqual(this,n2); + should.deepEqual(msg,message); + should.strictEqual(msg,message); + done(); + }); + n1.send(message); + messageReceived.should.be.exactly(0); + }); + it('emits a single message - synchronous mode', function(done) { var flow = { getNode: (id) => { return {'n1':n1,'n2':n2}[id]},