baobab icon indicating copy to clipboard operation
baobab copied to clipboard

Reducible, nested tree paths to set dynamic nodes

Open aultac opened this issue 9 years ago • 8 comments

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?

aultac avatar Dec 09 '15 05:12 aultac

Hello @aultac. This seems like a fine idea. Let me bring @jacomyal in this conversation.

Yomguithereal avatar Dec 09 '15 10:12 Yomguithereal

+1

abalmos avatar Dec 23 '15 19:12 abalmos

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 avatar Dec 23 '15 20:12 Yomguithereal

@Yomguithereal Can I ask what some of those issues were?

abalmos avatar Jan 01 '16 21:01 abalmos

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.

Yomguithereal avatar Jan 02 '16 14:01 Yomguithereal

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

aultac avatar Jan 06 '16 06:01 aultac

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...

gersongoulart avatar Feb 09 '16 21:02 gersongoulart

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.

Yomguithereal avatar Feb 10 '16 11:02 Yomguithereal