I have two collections: Commands
and CommandHistory
. I am trying to make an output that received the results of both of them, combined, where anything from CommandHistory
is bold. That is, something that looked like:
**Do the thing** <--| **Command History*
Doing thing <-|
thing is in progress <-| Commands
thing is done <-|
**Do the other thing** <-| **Command History**
I don't know what the other thing is <-| Commands
Here is a basic start of a helper:
log() {
const commandCursor = Commands.find({}, { sort: { timestamp: 1 } });
const commandHistory = CommandHistory.find({}, { sort: { timestamp: 1 } });
// what now? Need to concatenate them.
// `.fetch()` makes the interface seem non-reactive.
}
The only thing I can really think of is to make yet another (null
) collection and output everything from both collections into it, which seems like overkill.
Is it possible to concatenate the results of these two cursors, and still have it act reactively?
I think what you are looking for is mainly a way to combine both result sets. For that, you could use something like this:
log: function () {
var commands = Commands.find({}, { sort: { timestamp: 1 } }).map(function(i){i.origin='command'; return i;});
var history = History.find({}, { sort: { timestamp: 1} }).map(function(i){i.origin='history'; return i;});
var combined = _.union(commands, history);
return _.sortBy(combined, function(i) { return Number(i.timestamp) });
}
Here I'm adding a field called "origin" to identify where each entry came from. Also, I'm sorting the combined data set based on the timestamp, which I'm considering a simple Number for simplifying the example.
Once you have the data set combined, you can print them using another helper, which returns with or without **, depending on the origin:
output: function(obj) {
var text = obj.value || "";
if(obj.origin == 'history') text = "**"+text+"**";
return text
}
Here's a sample code you can try:
HTML: hello
<body>
{{> hello}}
</body>
<template name="hello">
<ul>
{{#each log}}
<li>{{output this}}</li>
{{/each}}
</ul>
</template>
JS:
Commands = new Mongo.Collection("commands");
History = new Mongo.Collection("history");
if (Meteor.isClient) {
// counter starts at 0
Session.setDefault('counter', 0);
Template.hello.helpers({
log: function () {
var commands = Commands.find({}, { sort: { timestamp: 1 } }).map(function(i){i.origin='command'; return i;});
var history = History.find({}, { sort: { timestamp: 1} }).map(function(i){i.origin='history'; return i;});
var combined = _.union(commands, history);
return _.sortBy(combined, function(i) { return Number(i.timestamp) });
},
output: function(obj) {
var text = obj.value || "";
if(obj.origin == 'history') text = "**"+text+"**";
return text
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
Commands.remove({});
History.remove({});
for (var i=1; i<5; i++) {
History.insert({value: 'history '+i, timestamp: 10*i});
for (var j=1; j<4; j++)
Commands.insert({value: 'command '+i+'.'+j, timestamp: 10*i+j});
}
});
}