mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Update split node docs
This commit is contained in:
parent
8f8df4971c
commit
d82fe95076
@ -34,6 +34,18 @@
|
||||
<li><b>array</b> - a message is sent for each element of the array</li>
|
||||
<li><b>object</b> - a message is sent for each key/value pair of the object. <code>msg.parts.key</code> is set to the key of the property.</li>
|
||||
</ul>
|
||||
<p>Each message is sent with the <code>msg.parts</code> property set. This is
|
||||
an object that provides any subsequent <i>join</i> node the necessary information
|
||||
for it to reassemble the messages back into a single one. The object has the following
|
||||
properties:</p>
|
||||
<ul>
|
||||
<li><b>id</b> - an identifier for the group of messages</li>
|
||||
<li><b>index</b> - the position within the group</li>
|
||||
<li><b>count</b> - the total number of messages in the group</li>
|
||||
<li><b>type</b> - the type of message - string/array/object</li>
|
||||
<li><b>ch</b> - for a string, the character used to split</li>
|
||||
<li><b>key</b> - for an object, the key of the property this message was created from</li>
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -67,7 +79,7 @@
|
||||
</div>
|
||||
<div class="node-row-custom">
|
||||
<div class="form-row node-row-property">
|
||||
<label>Join each </label>
|
||||
<label>Combine each </label>
|
||||
<input type="text" id="node-input-property" style="width:300px;">
|
||||
<input type="hidden" id="node-input-propertyType">
|
||||
</div>
|
||||
@ -113,17 +125,30 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="join">
|
||||
<p>A function that joins <code>msg.payload</code> from multiple msgs to create a single msg out.</p>
|
||||
<p>Other properties of the msg are not guaranteed as they could come from any of the incoming msgs.</p>
|
||||
<p>An optional <i>count</i> can be set that waits for that many <code>payload</code> to arrive before passing on the new message.</p>
|
||||
<p>An optional <i>timeout</i> can be set that can then send the incomplete message, drop the message or raise a catchable error.</p>
|
||||
<p>An optional <i>join character</i> can be set that can be used for joining multiple payloads together and returns a
|
||||
string rather than an array.</p>
|
||||
<p>When used with a <b>split</b> node the <i>count</i> and <i>join character</i> are automatically set - but can be
|
||||
overridden by values in the configuration.</p>
|
||||
<p>Messages can be joined into an <i>array</i> or <i>object</i>. To be joined into an object the incoming message must
|
||||
have either a <code>msg.key</code> or <code>msg.topic</code> property - or <code>msg.payload</code> should
|
||||
be an object with properties.</p>
|
||||
<p>A function that joins the a sequence of messages into a single message.</p>
|
||||
<p>When paired with the <b>split</b> node, it will automatically join the messages
|
||||
to reverse the split that was performed.</p>
|
||||
<p>It can be used without the split node by configuring the required behaviour.</p>
|
||||
<p>The type of the resulting message property can be a string, array or object. All of the other message
|
||||
properties are taken from the last message received before the message is sent.</p>
|
||||
<p>A <i>count</i> can be set for how many messages should be received before generating the output message</p>
|
||||
<p>A <i>timeout</i> can be set to trigger sending the new message using whatever has been received so far.</p>
|
||||
<p>If the node is set to construct a string, a <i>join character</i> can be set.</p>
|
||||
<p>If the node is set to construct an object, the key used to store each received property can be taken from
|
||||
an identified message property.</p>
|
||||
<p>The automatic behaviour relies on the received messages to have <b>msg.parts</b> set.
|
||||
The object has the following properties:</p>
|
||||
<ul>
|
||||
<li><b>id</b> - an identifier for the group of messages</li>
|
||||
<li><b>index</b> - the position within the group</li>
|
||||
<li><b>count</b> - the total number of messages in the group</li>
|
||||
<li><b>type</b> - the type of message - string/array/object</li>
|
||||
<li><b>ch</b> - for a string, the character used to split</li>
|
||||
<li><b>key</b> - for an object, the key of the property this message was created from</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -174,7 +199,7 @@
|
||||
types:['msg', {value:"full",label:"complete message",hasValue:false}]
|
||||
})
|
||||
$("#node-input-key").typedInput({
|
||||
types:['msg']
|
||||
types:['msg', {value:"merge",label:"",hasValue: false}]
|
||||
})
|
||||
|
||||
$("#node-input-build").change();
|
||||
|
@ -38,7 +38,7 @@ module.exports = function(RED) {
|
||||
msg.payload = a[i];
|
||||
msg.parts.index = i;
|
||||
msg.parts.count = a.length;
|
||||
node.send(msg);
|
||||
node.send(RED.util.cloneMessage(msg));
|
||||
}
|
||||
}
|
||||
else if ((typeof msg.payload === "object") && !Buffer.isBuffer(msg.payload)) {
|
||||
@ -52,7 +52,7 @@ module.exports = function(RED) {
|
||||
msg.parts.key = p;
|
||||
msg.parts.index = j;
|
||||
msg.parts.count = l;
|
||||
node.send(msg);
|
||||
node.send(RED.util.cloneMessage(msg));
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
@ -70,8 +70,11 @@ module.exports = function(RED) {
|
||||
this.mode = n.mode||"auto";
|
||||
this.property = n.property||"payload";
|
||||
this.propertyType = n.propertyType||"msg";
|
||||
if (this.propertyType === 'full') {
|
||||
this.property = "payload";
|
||||
}
|
||||
this.key = n.key||"topic";
|
||||
this.timer = (this.mode === "auto") ? 0 : Number(n.timeout || 0);
|
||||
this.timer = (this.mode === "auto") ? 0 : Number(n.timeout || 0)*1000;
|
||||
this.timerr = n.timerr || "send";
|
||||
this.count = Number(n.count || 0);
|
||||
this.joiner = (n.joiner||"").replace(/\\n/g,"\n").replace(/\\r/g,"\r").replace(/\\t/g,"\t").replace(/\\e/g,"\e").replace(/\\f/g,"\f").replace(/\\0/g,"\0");
|
||||
@ -85,9 +88,9 @@ module.exports = function(RED) {
|
||||
delete inflight[partId];
|
||||
|
||||
if (group.type === 'string') {
|
||||
group.msg.payload = group.payload.join(group.joinChar);
|
||||
RED.util.setMessageProperty(group.msg,node.property,group.payload.join(group.joinChar));
|
||||
} else {
|
||||
group.msg.payload = group.payload;
|
||||
RED.util.setMessageProperty(group.msg,node.property,group.payload);
|
||||
}
|
||||
if (group.msg.hasOwnProperty('parts') && group.msg.parts.hasOwnProperty('parts')) {
|
||||
group.msg.parts = group.msg.parts;
|
||||
@ -101,7 +104,7 @@ module.exports = function(RED) {
|
||||
try {
|
||||
var property;
|
||||
if (node.mode === 'auto' && (!msg.hasOwnProperty("parts")||!msg.parts.hasOwnProperty("id"))) {
|
||||
// TODO: log warning - no msg.parts in auto mode, ignoring
|
||||
node.warn("Message missing msg.parts property - cannot join in 'auto' mode")
|
||||
return;
|
||||
}
|
||||
if (node.propertyType == "full") {
|
||||
@ -143,7 +146,11 @@ try {
|
||||
}
|
||||
}
|
||||
if (payloadType === 'object' && (propertyKey === null || propertyKey === undefined || propertyKey === "")) {
|
||||
//TODO: log error - no key property found for object
|
||||
if (node.mode === "auto") {
|
||||
node.warn("Message missing 'msg.parts.key' property - cannot add to object");
|
||||
} else {
|
||||
node.warn("Message missing key property 'msg."+node.key+"' '- cannot add to object")
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!inflight.hasOwnProperty(partId)) {
|
||||
|
@ -58,7 +58,7 @@ describe('SPLIT node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should split a string into characters', function(done) {
|
||||
it('should split a string into new-lines', function(done) {
|
||||
var flow = [{id:"sn1", type:"split", wires:[["sn2"]]},
|
||||
{id:"sn2", type:"helper"}];
|
||||
helper.load(splitNode, flow, function() {
|
||||
@ -74,7 +74,7 @@ describe('SPLIT node', function() {
|
||||
if (msg.parts.index === 2) { msg.payload.should.equal("v"); }
|
||||
if (msg.parts.index === 3) { msg.payload.should.equal("e"); done(); }
|
||||
});
|
||||
sn1.receive({payload:"Dave"});
|
||||
sn1.receive({payload:"D\na\nv\ne"});
|
||||
});
|
||||
});
|
||||
|
||||
@ -146,7 +146,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should join things into an array after a count', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], count:3, joiner:","},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], count:3, joiner:",",mode:"custom"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -160,7 +160,7 @@ describe('JOIN node', function() {
|
||||
//msg.payload[2].a.should.equal(1);
|
||||
done();
|
||||
}
|
||||
catch(e) { }//console.log(e); }
|
||||
catch(e) {done(e);}
|
||||
});
|
||||
n1.receive({payload:1});
|
||||
n1.receive({payload:true});
|
||||
@ -169,7 +169,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should join things into an object after a count', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], count:5, build:"object"},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], count:5, build:"object",mode:"custom"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -186,7 +186,7 @@ describe('JOIN node', function() {
|
||||
msg.payload.g.should.have.property("f",6);
|
||||
done();
|
||||
}
|
||||
catch(e) { }//console.log(e); }
|
||||
catch(e) { done(e)}
|
||||
});
|
||||
n1.receive({payload:1, topic:"a"});
|
||||
n1.receive({payload:"2", topic:"b"});
|
||||
@ -198,7 +198,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should join strings with a specifed character after a timeout', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:50, count:10, joiner:","},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"string", timeout:0.05, count:10, joiner:",",mode:"custom"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -209,7 +209,7 @@ describe('JOIN node', function() {
|
||||
msg.payload.should.equal("a,b,c");
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
catch(e) { done(e) }
|
||||
});
|
||||
n1.receive({payload:"a"});
|
||||
n1.receive({payload:"b"});
|
||||
@ -218,7 +218,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should join strings with a specifed character and complete when told to', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:5000, count:100, joiner:"\n"},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"string", timeout:5, count:100, joiner:"\n",mode:"custom"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -229,7 +229,7 @@ describe('JOIN node', function() {
|
||||
msg.payload.should.equal("Hello\nNodeRED\nWorld\n");
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
catch(e) { done(e) }
|
||||
});
|
||||
n1.receive({payload:"Hello"});
|
||||
n1.receive({payload:"NodeRED"});
|
||||
@ -254,7 +254,7 @@ describe('JOIN node', function() {
|
||||
msg.payload[3].should.equal(4);
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:111}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:111}});
|
||||
@ -278,7 +278,7 @@ describe('JOIN node', function() {
|
||||
msg.payload.should.have.property("d",4);
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222, key:"c", type:"object"}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222, key:"b", type:"object"}});
|
||||
@ -287,31 +287,8 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it.skip('should join split things, missing some after a timeout', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:50},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.an.Array;
|
||||
(msg.payload[0] === undefined).should.be.true;
|
||||
msg.payload[1].should.equal(2);
|
||||
msg.payload[2].should.equal(3);
|
||||
(msg.payload[3] === undefined).should.be.true;
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
});
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:333}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:333}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should join split things, send when told complete', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:250},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:0.250},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -326,7 +303,7 @@ describe('JOIN node', function() {
|
||||
msg.payload[3].should.equal(4);
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:444} });
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:444} });
|
||||
@ -335,7 +312,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should join split strings back into a word', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]]},
|
||||
var flow = [{id:"n1", type:"join", mode:"auto", wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -347,35 +324,12 @@ describe('JOIN node', function() {
|
||||
msg.payload.should.equal("abcd");
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:"a", parts:{index:0, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"d", parts:{index:3, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"c", parts:{index:2, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"b", parts:{index:1, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"a", parts:{type:'string',index:0, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"d", parts:{type:'string',index:3, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"c", parts:{type:'string',index:2, count:4, ch:"", id:555}});
|
||||
n1.receive({payload:"b", parts:{type:'string',index:1, count:4, ch:"", id:555}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should join split strings back overriding the join char', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], joiner:":"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.an.Array;
|
||||
msg.payload.should.equal("a:b:c:d");
|
||||
done();
|
||||
}
|
||||
catch(e) { console.log(e); }
|
||||
});
|
||||
n1.receive({payload:"a", parts:{index:0, count:4, ch:"", id:666}});
|
||||
n1.receive({payload:"d", parts:{index:3, count:4, ch:"", id:666}});
|
||||
n1.receive({payload:"c", parts:{index:2, count:4, ch:"", id:666}});
|
||||
n1.receive({payload:"b", parts:{index:1, count:4, ch:"", id:666}});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user