Configuration
There is a second argument to the store that sets configuration. 99% of the time you should not have to worry/care about these options.
const myConfiguredCollection = collection( {x: 1, y: 2}, {quiet: true, compItems: myCompFunction, compKeys: myCompFunction});
Quiet: boolean
For upcoming observation utilities, the "quiet" option blocks the collection from broadcasting feedback to the onChange
method.
Comparators: advanced
functions like get
, deleteKey
, deleteItem
, hasKey
or hasItem
by default use a comparator to see if a value
in the collection matches the argument(s) from the call. By default it uses ===
conmparison. So, an equivalent value
will NOT be an equivalent match, if they are compound types.
const mapC = collect(new Map([])); mapC .set(1, 'happy') .set({ x: 1, y: 1 }, 'sad') .set('Bob', 'angry') .set(Symbol('unique'), 'lonely'); console.log('mapC=', mapC.value); console.log('numbers'); console.log('has 1', mapC.hasKey(1)); console.log('objects'); console.log('has {x: 1, y: 1}', mapC.hasKey({ x: 1, y: 1 })); console.log('strings'); console.log('has "Bob"', mapC.hasKey('Bob')); console.log('symbols'); console.log('has Symbol("unique")', mapC.hasKey(Symbol('unique'))); /* mapC= Map(4) { 1 => 'happy', { x: 1, y: 1 } => 'sad', 'Bob' => 'angry', Symbol(unique) => 'lonely' } numbers has 1 true objects has {x: 1, y: 1} false strings has "Bob" true symbols has Symbol("unique") false */
Many of these examples fail for complex types (object, Symbol) because a new item reference is created with each line of code.
We can fix this.
the comparator used here is .sameKey
. This property can be set in creation or changed at any time.
import toString from 'lodash.tostring'; const mapC = collect(new Map([]), { compKeys: (item1, item2) => { try { item1 = JSON.stringify(item1); } catch (_e) { item1 = toString(item1); } try { item2 = JSON.stringify(item2); } catch (_e2) { item2 = toString(item2); } console.log('comparing', item1, 'and', item2); return item1 === item2; }, }); mapC .set(1, 'happy') .set({ x: 1, y: 1 }, 'sad') .set('Bob', 'angry') .set(Symbol('unique'), 'lonely'); console.log('mapC=', mapC.value); console.log('numbers'); console.log('has 1', mapC.hasKey(1)); console.log('objects'); console.log('has {x: 1, y: 1}', mapC.hasKey({ x: 1, y: 1 })); console.log('strings'); console.log('has "Bob"', mapC.hasKey('Bob')); console.log('symbols'); console.log('has Symbol("unique")', mapC.hasKey(Symbol('unique'))); /* mapC= Map(4) { 1 => 'happy', { x: 1, y: 1 } => 'sad', 'Bob' => 'angry', Symbol(unique) => 'lonely' } numbers has 1 true objects comparing 1 and {"x":1,"y":1} comparing {"x":1,"y":1} and {"x":1,"y":1} has {x: 1, y: 1} true ^ ^ ^ ^ This is the important difference -- an object LIKE the compared-to key is registered as present strings has "Bob" true symbols comparing 1 and undefined comparing {"x":1,"y":1} and undefined comparing "Bob" and undefined comparing undefined and undefined has Symbol("unique") true */
By flattening complex objects to stringy representations, things that "look" the same are considered equivalent.
There are two comparators:
compKeys(key1, key2, collection?) => boolean
demonstrated above; used in Map.get
, hasKey
, deleteKey
compItems(key1, k2, colletcion>) => boolean
used in hasItem, deleteItem
Temporary comparators
withComp(action : function, comp: {compItems?: function, compKeys?: function})
: result of action
You can temporarily assert a comparator for an operation via "withComp". The passed in comparators are used during the execution of the function, then returned to their previous values.
The result of the action, if any, is returned.
Beware - this is a synchronous change; use of async functions or promises will not benefit from the temporary comparators.