Problem with "registerType"

313 views
Skip to first unread message

Farshad P

unread,
Mar 17, 2015, 8:03:36 AM3/17/15
to node...@googlegroups.com

I need to modify the constructor of the nodes. Unfortunately, I found 4 different definitions for registerType (which registers the node constructors). I was wondering if somebody can clarify the functionality of each of them? Thanks

For example, for email node, I found the following 4 codes:



1)  In email.js:

RED.nodes.registerType("e-mail",EmailNode,{
        credentials: {
            userid: {type:"text"},
            password: {type: "password"},
            global: { type:"boolean"}
        }
    });



2)   In email.html

RED.nodes.registerType('e-mail in',{
        category: 'social-input',
        color:"#c7e9c0",
        defaults: {
            repeat: {value:"300",required:true},
            server: {value:"imap.gmail.com",required:true},
            port: {value:"993",required:true},
            name: {value:""}
        },
        credentials: {
            userid: {type:"text"},
            password: {type: "password"},
            global: { type:"boolean"}
        },
        inputs:0,
        outputs:1,
        icon: "envelope.png",
        label: function() {
            return this.name||"email";
        },
        labelStyle: function() {
            return (this.name||!this.topic)?"node_label_italic":"";
        },
        oneditprepare: function() {
            if (this.credentials.global) {
                $('#node-tip').show();
            } else {
                $('#node-tip').hide();
            };
        }
    });

3) In register.js:

registerType: registry.registerNodeConstructor,


registerNodeConstructor: function(type,constructor) {
            if (nodeConstructors[type]) {
                throw new Error(type+" already registered");
            }
            //TODO: Ensure type is known - but doing so will break some tests
            //      that don't have a way to register a node template ahead
            //      of registering the constructor
            util.inherits(constructor,Node);
            nodeConstructors[type] = constructor;
            events.emit("type-registered",type);
        }


4)  In index.js

   // Node type registry
    registerType: registerType,

function registerType(type,constructor,opts) {
    if (opts && opts.credentials) {
        credentials.register(type,opts.credentials);
    }
    registry.registerType(type,constructor);
}

Antoine Aflalo

unread,
Mar 17, 2015, 8:08:31 AM3/17/15
to node...@googlegroups.com
Hello Farshad,

1) Register the node in the definition of the Node of Node-RED. Server-side.
2) Same as 1) but Client-Side.
3) Definition of the the method in the server-side
4) Definition of the method in the client-side.

Question:
Why do you need to modify it ?

--
http://nodered.org
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Antoine Aflalo

Farshad P

unread,
Mar 17, 2015, 8:39:58 AM3/17/15
to node...@googlegroups.com
Thank you Antoine. In fact, I am trying to teardown some parts of the node-red to build an in-house ALERT system (cluster-based)! Since my major is VLSI design rather than software, I confused with the code.

So I am wondering how these functions are related to each other? In the editor, when I instantiate a new node (assume Email_out), the client send config to Email.js and function "function EmailNode(config)". This function then calls "RED.nodes.createNode(this,n);" in order to inherit the basic properties of nodes and the rest of the code is dedicated to the definition of this node. The node is activated when a message is ready for it: 

this.on('input', function(msg) {
     })

Finally, the node performs some proecessing on the message, and prepare a new message. Finally, the node sends the new message to
the other nodes of the flow using:
node.send(msg);

So, when we use this "registertype" in the above flow? what would be the order of calling these functions? I appreciate if you could kindly comment on the overall flow of the node-red?



Thanks in advance


. Do you mind helping me to figure out the other parts of this puzzle? 

Antoine Aflalo

unread,
Mar 17, 2015, 8:50:25 AM3/17/15
to node...@googlegroups.com
When NR is launched, it scan it's configuration and the nodes directory (also the node_module).
When it encounter a node, it will execute the JS file, that will register itself in the NodeType registry of Node-RED (that's for the .js, for the .html I haven't check how does it works)

In order :
At Launch :
1) RegisterType to register a Node-Type. A Node type is a schema for a node, it contains the definition of a Node.

When a Flow is deployed:
2) if the flow contain a Node of your NodeType, the function you register will be called with the information of the Node (filled by the editor). In your example : EmailNode(config) where config contain the configuration information of the Real Node in the flow.

When a message is given at the input :
3) this.on('input', function(msg) {
}) 

This the the "basic" workflow of a Node/NodeType in Node-RED.

Nicholas O'Leary

unread,
Mar 17, 2015, 9:09:58 AM3/17/15
to Node-RED Mailing LIst
RED.nodes.registerType in the .html file is called once when the node is added to the editor palette. It registers the details of the node type, such as icon, colour etc, and any node-specific behaviour needed when editing the node. This is what makes it appear in the palette.

As Antoine has outlined, RED.nodes.registerType in the .js file registers the constructor of the node type with the runtime. It is called once on start-up for each node-type that needs to be registered. It does not get called as part of the workflow of deploying a new flow configuration and instantiating the individual nodes of the flow.

Nick

farshad firouzi

unread,
Mar 17, 2015, 10:44:14 AM3/17/15
to node...@googlegroups.com
Hi Nick, Antoine

Now, I almost understand the workflow. But I have a minor issue with the order of the functions.


1) First, NR scans the Noode-red/nodes directory and registers all the node types. In case of Email node, we have:


 RED.nodes.registerType("e-mail",EmailNode, {credentials: {}});

In which EmailNode(n) calls the following routine to crease a node:

function EmailNode(n) {
        RED.nodes.createNode(this,n);
}



2) Now in Flow.js we have the following piece of code:

function createNode(type,config) {
    var nn = null;
    var nt = typeRegistry.get(type);
    if (nt) {
        try {
            nn = new nt(clone(config));
        }
        catch (err) {
            log.warn(type+" : "+err);
        }
    } else {
        log.warn("unknown type: "+type);
    }
    return nn;
}

In which, "typeRegistry.get(type)" is defined in "register.js" as follows:

 get: registry.getNodeConstructor,

 getNodeConstructor: function(type) {
            var id = nodeTypeToId[type];

            var config;
            if (typeof id === "undefined") {
                config = undefined;
            } else {
                config = moduleConfigs[getModule(id)].nodes[getNode(id)];
            }

            if (!config || (config.enabled && !config.err)) {
                return nodeConstructors[type];
            }
            return null;
        },



Now, I think there is a loop between the above functions.
In EmailNode(), we need createNode(). And in the createNode(), we call typeRegistry.get(type) which in turn needs EmailNode(). Becuase EmailNode() is already registered by the system (i.e.,   RED.nodes.registerType("e-mail",EmailNode,{});

Could you plz comment on that. Thanks

Farshad

--
http://nodered.org
---
You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/eJQeQCiiSYw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+u...@googlegroups.com.

Nicholas O'Leary

unread,
Mar 17, 2015, 10:46:30 AM3/17/15
to Node-RED Mailing LIst
Calling
     RED.nodes.registerType("e-mail",EmailNode, {credentials: {}});

Does not call the EmailNode function at that point in time. It passes a reference to the function so that it can be called later when a node instance is required as part of deploying a flow.

Nick

Antoine Aflalo

unread,
Mar 17, 2015, 10:51:52 AM3/17/15
to node...@googlegroups.com
Usecase :
User make modification to his flow. He clicks on deploy (full).

Client Side:
Pack the flow and send it to the server.

Server:
Get the flow, parse it.
Split the node type and the configuration of the node (type and node of createNode())
Go into the registry and get the definition (EmailNode()) of the Node, and apply it to the the node.

The Node definition (EmailNode()) call RED.nodes.createNode() to make the EmailNode inheritate all the attribute of a node.

the createNode of Flows.js is not the same as the one in node.js. The first one is used to apply the NodeType to a node included in a flow. The second one is to inherit the property of a Node-RED node.

farshad firouzi

unread,
Mar 18, 2015, 6:46:47 AM3/18/15
to node...@googlegroups.com
Great! Thanks...
Reply all
Reply to author
Forward
0 new messages