hey there, im trying to create a custom node that may send a message via a callback. for that purpose i have assigned the this from the constructor-function to the variable "node" like in the docs.
whenever i try to use node.send, i crash node-red becuase the the context doesnt contain the correct _flow, i have also console.logged the this of the constructor for context:
XYZConnectorConstructor {
id: '40c25bbbcb943b6c',
type: 'xyz-node',
z: '96daf2ba776b0cab',
g: undefined,
_closeCallbacks: ,
_inputCallback: [AsyncFunction (anonymous)],
_inputCallbacks: null,
_expectedDoneCount: 0,
wires: [ [ '8357e6c66d166b6b' ], [ 'fbc2f2e3072130bc' ] ],
_wireCount: 2,
send: [Function (anonymous)]
}
what possible causes could that have? id really like to use use node.send for doing some stuff.
i do have node-red embedded for the option of adding custom middleware and stuff, but shouldnt change anything, right?
It would help if you could share some code so that we can see the context.
The send function should be available once you have done RED.nodes.createNode(this, config)
which is in the callback function to pass to RED.nodes.registerType(mod.nodeName, nodeInstance)
(I always use a function called nodeInstance
).
Example here: RED.nodes.registerType(mod.nodeName, nodeInstance)
If you are sending a msg in response to an incoming msg, then the input
callback function contains its own send
function.
Are you using arrow functions?
Try using regular callbacks e.g. function(x) { ... }
instead of (x => ...)
my code basicially goes as follows:
const nodeInit: NodeInitializer = (Red): void => {
function BaseNodeNodeConstructor(
this: Node,
config: XYZ
): void {
Red.nodes.createNode(
this as Node<{}>,
{ ...config, outputs: 2 } as NodeDef
);
const callMap = new Map<string, Function>();
const node = this
this.on("input", async (msg, send, done) => {
const input = msg as XYZMessage
if (input.wlCallId) {
callMap.get(input.wlCallId)?.(input);
callMap.delete(input.wlCallId);
done();
return;
}
node.send([input, null]);
const out = {
...input,
};
send([null, out]);
done();
});
}
Red.nodes.registerType("XYZ-definer-node", BaseNodeNodeConstructor, {
outputs: 2,
} as any);
};
export = nodeInit
im not sure what i am missing
i have already refactored it to use the function-keyword, to the same result
the thing is, logging out the this keyword yields me something that looks like a valid node, just without _flow
Including the NodeInitializer
?
What does the final dist code look like. Is it in a repo we can look at?
the problem lies in what i just quoted -.-
turn out spreading the config doesnt copy all the fields, which went unnoticed by me.
I've always found it extremely odd that the createNode function does not itself transfer the config properties to this
.
The way you are doing things does not, I think, need you to create the node
object. If you are only using arrow fns then this
remains the same.
In fact, even if you create a standard function definition (at the module level) that you pass to the registerType
callback, you still don't need to create a node
object. You can continue to use this
just fine. I very rarely have to create a node
object any more - check out the link I shared.