Skip to content

Instantly share code, notes, and snippets.

@feliperohdee
Last active November 30, 2017 13:01
Show Gist options
  • Save feliperohdee/82ee5f485288d7c13f04acd293adff98 to your computer and use it in GitHub Desktop.
Save feliperohdee/82ee5f485288d7c13f04acd293adff98 to your computer and use it in GitHub Desktop.
Safe object manipulators and observable pattern store
// safe object getter setter
// get({}, ['prop1', 'prop2], [])
// set({}, ['prop1', 'prop2], [])
const isString = path => typeof path === 'string';
export function get(object, path, defaultValue = null) {
const string = isString(path);
const length = path.length;
if (string || length === 1) {
return object[string ? path : path[0]] || defaultValue;
}
let index = 0;
while (object && index < length) {
object = object[path[index++]];
}
return (index && index === length) && object || defaultValue;
}
export function set(object, path, value) {
const string = isString(path);
const length = path.length;
if (string || path.length) {
object[string ? path : path[0]] = value;
} else {
object[path[0]] = path.reduceRight((reduction, token, index) => {
if (index === path.length - 1) {
return value;
}
return {
[path[index + 1]]: reduction
};
}, {});
}
return object;
}
// simple store with observable pattern
import {
get,
set
} from './object';
export default class Store {
_handlers = [];
get(path, defaultValue = null) {
return get(this, path, defaultValue);
}
set(path, value, event = null) {
set(this, path, value);
this.next(event, this);
return this;
}
next(...args) {
this._handlers.forEach(handler => handler(...args));
}
subscribe(fn, onUnsubscribe) {
this._handlers.push(fn);
return () => this.unsubscribe(fn, onUnsubscribe);
}
unsubscribe(fn, callback) {
this._handlers = this._handlers.filter(fn_ => fn_ !== fn);
callback && callback();
}
setState(state = {}, event = null) {
Object.keys(state).forEach(key => this[key] = state[key]);
this.next(event, this);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment