baobab
baobab copied to clipboard
Reducible, nested tree paths to set dynamic nodes
A somewhat common use of a Monkey is to lookup an item from a list based on a "current" id, i.e.
var tree = Baobab({
currentEventid: 12,
events: {
12: { info: 'about event 12' },
},
event: monkey({
cursors: {
currentEventid: [ 'currentEventid' ],
events: [ 'events' ],
},
get: function(c) {
return c.events[c.currentEventid],
}
}),
});
console.log(tree.get([ 'event' ]);
// prints: { info: 'about event 12' }
Works great for getting the current thing, not so great for setting some property of the current thing. I was thinking about something like this as a compact way to set information on the thing looked up by the monkey:
tree.set([ 'events', [ 'currentEventid' ], 'info' ], 'different info on 12!');
console.log(tree.get(['event']));
// prints: { info: 'different info on 12!' }
I've done it outside Baobab thus far like this:
var reducePath = function(tree, state_path) {
return _.map(state_path, function(p) {
if (!_.isArray(p)) return p;
return tree.get(reducePath(p));
});
};
tree.set(reducePath(tree, [ 'events', [ 'currentEventid' ], 'info']), 'different info!');
Is it worth considering adding support to Baobab (if it doesn't already exist?) for nesting arrays of paths inside tree paths?
Hello @aultac. This seems like a fine idea. Let me bring @jacomyal in this conversation.
+1
I took a step back here and remembered that I already implemented something of the kind in v1 and it ended up to be a chaotic mess. Will need a lot of thinking before re-implementing something of the kind.
@Yomguithereal Can I ask what some of those issues were?
Issues with dependencies. Because basically, such a cursor becomes a monkey in fact. That is to say you would expect such cursor to update whenever either its path or the reduced path is updated. And this is recursive.
Perhaps implementation could be simplified by treating the nested paths as monkeys themselves? That's what I have to do manually now in a tree for such lookups. The advantage here is that full knowledge of the path should allow for a '2-way' monkey that supports set as well as get
Would it be the case to create a set
method in the monkey? As I was reading, this idea came to my mind:
var tree = Baobab({
currentEventid: 12,
events: {
12: { info: 'about event 12' },
},
event: monkey({
cursors: {
currentEventid: [ 'currentEventid' ],
events: [ 'events' ],
},
get: function(c) {
return c.events[c.currentEventid],
},
set: function(path, data) {
// In here you can do whatever updates to the tree you may possibly wish for, eg.:
var currentEventid = tree.get('currentEventid');
tree.set(['events', currentEventid, path], data)
}
}),
});
tree.select([ 'event' ]).set('info', 'different info!');
Just food for thought...
You don't need set in monkeys to perform what you want to do. Just listen to a cursor or a watcher and perform writes on the tree on their update
events.