How to synchronize two input messages?

Using the screenshot I'm trying to popup a message box using a node which accepts

  • the title of the message box
  • the message to show

Here is the node function

function collectInputs(msg, context) {
	var title = context.get('title') || 'default title';
	var message = context.get('message') || 'default message';
	switch (msg.topic) {
		case 'title':
			title = msg.payload;
			context.set('title', title);
			break;
		case 'message':
            title = msg.payload;
            context.set('message', message);
            break;
	}
	let inputs = [
		{payload: title, topic: title},
		{payload: message, topic: message}
	];
    return inputs;
}

.....

 node.on('input', function(input, send, done) {
    let inputs = collectInputs(input, node.context());

    prompt(inputs[0].payload, inputs[1].payload);

    send(inputs);
    if (done) {
        done();
    }
}
}

However, it seems that only the message title is filed with the input message. I suspect that this is a race condition that I'm not copying with properly.

I do know there is a Join node to consolidate messages into a single input, but I want to avoid introduce a Join for EVERY node with multiple inputs.

What I'm I missing here?

A basic concept that should be understood is that messages can never arrive at the input of a node at the same time.

You can however join messages.

See this article in the cookbook for an example of how to join messages into one object.

If you don't want to use a Join node you will have to replicate the Join function in your node. Save the previous values for each topic in the node context then you can get the latest value of each.

Thanks, Colin. @Colin
That's something I was trying in my post with the code snippets.
However, it seems that context is working in an unexpected order.
Am I using it in the wrong way?

Ah yes, so you are. I am not sure it is valid to pass the context into a function like that. I would test it initially just using the context inline rather than passing it in, and see if that works.

@kakyoism I am curious, what type of strange node are you using to feed your messages into? The one that says "Hello World"

It's just a node that tries to receive two inputs: title/message, to pop up a message box with the inputs. @Gunner

I've just tried to inline that function and the result is the same. The extracted info from context is out of order @Colin

inputs: [{"payload":"my name is ","topic":"my name is "},{"payload":"default message","topic":"default message"}]

I expect to have

inputs: [{"payload":"my name is ","topic":"title"},{"payload":"a weird name","topic":"message"}]

And what is this node called?

it's called hello_world. @Gunner

I regret even asking :crazy_face: It sure isn't any of the old and apparently meaningless nodes called "hello world" that I can find in the palette.

EDIT - Based on your prior posts, I think I figured out that you are making some form of a contrib-node of your own... thus my inability to find more info about it :stuck_out_tongue:

Hmm! Something wrong there I think.

Argh! You are totally right. @Colin
I'm sorry to have you guys debug this with me now...

But even with that fixed, I still don't want the "default message" to kick in at all. It seems inevitable with the two branches of Change nodes.

Besides, I just found out a fundamental flaw of my approach:

The node inputs/outputs are all key-value pairs, i.e., named. So I can't guarantee that the names of the other nodes' outputs would match the exact input names of the node of concern.

This is a bit annoying because I really want to replicate other FBP-inspired systems' UX:

  • Simply try to connect any output port to any input port
  • If they work with each other, they just work.
  • Otherwise, the wire simply won't connect, and error logs clearly show the incompatibility.

I know this must be hard because JS generally allows passing anything around. But from the UX point of view I'd love to minimize the adaptors between custom nodes. Maybe I'm asking too much with Node-RED. Are there good design patterns to handle many-to-many in-out ports situations with minimum adaptations?

I now start to understand why systems like MaxMSP forces a port evaluation order based on the port visual topology around the node shape, e.g., right-to-left, top-to-bottom.

But I suspect that supporting multiple inputs in the above fashion would end up with a more intuitive user experience. Nodes would then be decoupled without the name-matching issues.

On a side node, this XKCD post seems very relevant IMHO.

I don't fully understand what you are trying to achieve. Can you explain in words of one syllable (or occasionally 2)?

@Colin Well, I wanted to directly connect any number of outputs to any number of inputs without having to worry about anything in-between, like this

But I've got the answer from another post on this forum.