Type error: RED.comms.subscribe

Hello
I am getting an error that
Property 'subscribe' does not exist on type 'NodeAPIComms'.
when trying to subscribe to notifications.
RED.comms.subscribe("notification/#", (topic, payload) => {

looking at the types file I can see there is only a definition for the publish property.

Can anyone shed any light on this? The readme suggests the last update to the types file was 8th March 2024.

Hi,

The Types aren't maintained by the Node-RED project, so I cannot vouch for their accuracy.

Where exactly are you trying to use that? Is that in the backend (the .js part of your node) or the frontend (the .html part of your node)?

Can you explain why you want to subscribe to notifications? They are an internal event between the runtime and editor. RED.comms isn't a public API we have documented for nodes to use - so it may not be the right thing for you to be using.

sure - perhaps there is another way to skin the proverbial cat.

I'm developing a node-red interface to matter, leveraging @Apollon77's work on matter.js.

the config node represents the matter server and aggregator.

each synthetic device should wait until the matter server (and aggregator) have been successfully brought on line before registering themselves against the aggregator.

My approach so far has been something like this:

emit("matterAggregatorStarted", matterAggregator)

but in testing I am seeing the logs start complaining about the number of listeners on this event. Not knowing any better, perhaps, I followed the advice here to create pubsub type behaviours.

Is there a better/more standardised way of runtime nodes listening for an internal trigger before they do something?

many thanks
Justin

Hi @jpadie

If you want to alert your nodes that something has initialised.
a way you should approach this (and one I use is as follows)

In your - lets call them client nodes to the config node.

Add a method to your config node

this.registerClient = (NodeID, callback) => {
   // Store callback referenced by the Node ID
}

In your client nodes

this.MyCallback = (event, body) => {
  // do magic
}

this.config.registerClient(this.id,this.MyCallback)

Then in the config node (and when time is right)

this.clients.each((c) => {
  c.callback('Im Ready Baby',<some fancy thing>)
})

I use this pattern often - and it works well
This doesn't use any form of signalling but more relationship driven communication

I used the word Should - but its just a possible way (and one that I use)

I'm pretty sure config nodes are started first - hence why this works (at least for me)

1 Like

@marcus-j-davies
thank you. I don't think that the idea quite works for me as the client nodes may not be instantiated at any particular moment (so when the config node iterates over the client collection it may not sweep them all up). However a minor adaptation in the config functoin should fix that and I'm very grateful for the pointer.

I will also submit a PR for the missing comms Types next week as it seems to be a mistaken omission rather than absent by design; and the comms API is documented; so worth Typing.

As @knolleary said the commas api is not a public one, so should not be considered to be stable, and may change without warning. (Unlikely , but…)

1 Like

I address this by returning the state during registration (sorry I should have included that)

Config

this.registerClient = (NodeID, callback) => {
   // Store callback referenced by the Node ID
   return <current state>
}

Client

const currentState = this.config.registerClient(this.id,this.MyCallback)
if(currentState.ready){
     doMagic() // else doMagic() is executed on the ready event you pass via the registered callbacks
}

This allows late to the party client nodes, being advised of the current state

1 Like

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