Skip to content

Instantly share code, notes, and snippets.

@ansarizafar
Forked from jacwright/svelte-observe.js
Created September 14, 2018 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ansarizafar/c81fc6e7671eedb358abe94431c187c6 to your computer and use it in GitHub Desktop.
Save ansarizafar/c81fc6e7671eedb358abe94431c187c6 to your computer and use it in GitHub Desktop.
One `observe` for all svelte needs.
export function observe(key, callback, opts) {
const single = !Array.isArray(key);
const keypaths = single ? [ key ] : key;
const parts = keypaths.map(keypath => keypath.replace(/\[(\d+)\]/g, '.$1').split('.'));
const keys = parts.map(parts => parts[0]);
const fn = callback.bind(this);
let last = parts.map(parts => getNestedValue(this.get(), parts));
if (!opts || opts.init !== false) {
single ? fn(last[0], undefined) : fn(last, last.map(_ => undefined));
}
return this.on(
opts && opts.defer ? 'update' : 'state',
({ changed, current, previous }) => {
if (!previous) return; // prevent double-firing if observing in oncreate
let i = keys.length;
while (i--) {
if (changed[keys[i]]) {
let j = parts.length;
const values = parts.map(parts => getNestedValue(current, parts));
if (!values.every((value, i) => value === last[i])) {
single ? fn(values[0], last[0]) : fn(values, last);
last = values;
}
return;
}
}
}
);
}
function getNestedValue(obj, parts) {
for (let i = 0; i < parts.length; i += 1) {
if (!obj) return undefined;
obj = obj[parts[i]];
}
return obj;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment