Node.send causing error: this._flow is undefined

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

↓ As I said ↓

1 Like

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.