Add merged object to Join node

This commit is contained in:
Nick O'Leary 2016-06-11 21:43:37 +01:00
parent 1cfad27d6f
commit 7302ac5871
3 changed files with 63 additions and 21 deletions

View File

@ -88,7 +88,8 @@
<select id="node-input-build" style="width:200px;">
<option id="node-input-build-string" value="string">a String</option>
<option value="array">an Array</option>
<option value="object">an Object</option>
<option value="object">a key/value Object</option>
<option value="merged">a merged Object</option>
</select>
</div>
<div class="form-row node-row-key">
@ -128,27 +129,30 @@
<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>The node can join either a specific property of each received message or,
if the output type is not string, the entire message.</p>
<p>The type of the resulting message property can be:</p>
<ul>
<li>a <b>string</b> - created by joining the property of each message with the specified join character.</li>
<li>an <b>array</b>.</li>
<li>a <b>key/value object</b> - created by using a property of each message to determine the key under which
the required value is stored.</li>
<li>a <b>merged object</b> - created by merging the property of each message under a single object.</li>
</ul>
The other properties of the output message are taken from the last message received before the result 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>
<p>If a message is received with the <b>msg.complete</b> property set, the output message is sent.</p>
<p>The automatic behaviour relies on the received messages to have <b>msg.parts</b> set. The split node generates
this property, but can be manually created. It 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">

View File

@ -154,7 +154,7 @@ try {
return;
}
if (!inflight.hasOwnProperty(partId)) {
if (payloadType === 'object') {
if (payloadType === 'object' || payloadType === 'merged') {
inflight[partId] = {
currentCount:0,
payload:{},
@ -186,6 +186,17 @@ try {
if (payloadType === 'object') {
group.payload[propertyKey] = property;
group.currentCount = Object.keys(group.payload).length;
} else if (payloadType === 'merged') {
if (Array.isArray(property) || typeof property !== 'object') {
node.warn("Cannot merge non-object types");
} else {
for (propertyKey in property) {
if (property.hasOwnProperty(propertyKey)) {
group.payload[propertyKey] = property[propertyKey];
}
}
group.currentCount++;
}
} else {
if (!isNaN(propertyIndex)) {
group.payload[propertyIndex] = property;

View File

@ -197,6 +197,33 @@ describe('JOIN node', function() {
});
});
it('should merge objects', function(done) {
var flow = [{id:"n1", type:"join", wires:[["n2"]], count:6, build:"merged",mode:"custom"},
{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.have.property("a",6);
msg.payload.should.have.property("b",2);
msg.payload.should.have.property("c",3);
msg.payload.should.have.property("d",4);
msg.payload.should.have.property("e",5);
done();
}
catch(e) { done(e)}
});
n1.receive({payload:{a:1}, topic:"a"});
n1.receive({payload:{b:2}, topic:"b"});
n1.receive({payload:{c:3}, topic:"c"});
n1.receive({payload:{d:4}, topic:"d"});
n1.receive({payload:{e:5}, topic:"e"});
n1.receive({payload:{a:6}, topic:"f"});
});
});
it('should join strings with a specifed character after a timeout', function(done) {
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"string", timeout:0.05, count:10, joiner:",",mode:"custom"},
{id:"n2", type:"helper"}];