Leaf's Value
There are no limitations on the Leaf's value - the first argument of the leaf. A leaf's value can be an object, a map, a string, number, Date, array, or any other Javascript variable type.
Objects and Maps will get cloned every time one of their values change; so it's not a good idea to use an object that
relies on its prototype for meaning; for instance putting a DOM object into a Leaf is probably going to be
problematic.
see setMeta
for how to attach complex objects to a state.
Compound Values
Objects, maps, and arrays are considered compound values;
they will(1) get setters inferred for their values in the .do
method collection.
A leaf's current value is accessed from the myLeaf.value
property.
You can get or set that value directly to update state:
const numberLeaf = new Forest(${value: 6});
const stringLeaf = new Forest(${value: 'Bob'});
const objectLeaf = new Forest({$value: {x: 0, y: 0}});
const mapLeaf = new Forest({$value: new Map([
['x', 0],
['y', 0]
])
});
numberLeaf.value = 10;
console.log('new number leaf value:', numberLeaf.value);
stringLeaf.value = 'Rick'
console.log('new string leaf value: ', stringLeaf.value);
objectLeaf.value = {y: 3, z: 6};
console.log('new object leaf value', objectLeaf.value);
mapLeaf.value =new Map([['y', 3], ['z', 6]]);
console.log('new map leaf value', mapLeaf.value);
/**
new number leaf value: 10
new string leaf value: Rick
new object leaf value { x: 0, y: 3, z: 6 }
new map leaf value Map(3) { 'x' => 0, 'y' => 3, 'z' => 6 }
*/
Keeping the same form
By default -- you can change the value to any type of content you want.
If you pass {type: true}
to the constructor,
Forest will block any attempts to change the form of the value to a different type.
const point = new Forest({$value: { x: 1, y: 2 }, type: true });
point.subscribe(value => console.log('value of point', value));
point.next({ x: 3, y: 4 });
try {
point.value = 'Bob'
} catch (err) {
console.log('bad form error: ', err);
}
point.next({ x: 5, y: 6 });
/**
value of point { x: 1, y: 2 }
value of point { x: 3, y: 4 }
bad form error: Error: incorrect form for leaf [ROOT]; wanted Symbol(form:object), got Symbol(form:value)...
value of point { x: 5, y: 6 }
*/
otherwise, by default, you can mangle your state's type all you like:
const point = new Forest({ x: 1, y: 2 });
point.subscribe(value => console.log('value of unguarded point', value));
point.next({ x: 3, y: 4 });
try {
point.next('Bob');
} catch (err) {
console.log('unguarded bad form error: ', err);
}
point.next({ x: 5, y: 6 });
/**
value of unguarded point { x: 1, y: 2 }
value of unguarded point { x: 3, y: 4 }
value of unguarded point Bob
value of unguarded point { x: 5, y: 6 }
*/
That being said there are side effects to changing the type/form of a Forest instance's value;
see /actions
for details on how it affects actions, and /children
for how it affects
child Leafs.
delKeys(name | names[])
If you want to actually delete an index, you can pass one or more keys to delKey
and it will remove them from a compound
object.
const objectLeaf = new Forest({x: 0, y: 0});
const mapLeaf = new Forest(new Map([
['x', 0],
['y', 0]
]));
objectLeaf.next({y: 3, z: 6});
console.log('new object leaf value', objectLeaf.value);
mapLeaf.next(new Map([['y', 3], ['z', 6]]));
console.log('new map leaf value', mapLeaf.value);
mapLeaf.delKeys('y');
console.log('new map leaf value without y', mapLeaf.value);
/**
new number leaf value: 10
new string leaf value: Rick
new object leaf value { x: 0, y: 3, z: 6 }
new map leaf value Map(3) { 'x' => 0, 'y' => 3, 'z' => 6 }
new map leaf value without y Map(2) { 'x' => 0, 'z' => 6 }
*/