Skip to content

Instantly share code, notes, and snippets.

@figloalds
Created June 19, 2019 14:41
Show Gist options
  • Save figloalds/86e0f577e9099fb2cdde1bae0f447423 to your computer and use it in GitHub Desktop.
Save figloalds/86e0f577e9099fb2cdde1bae0f447423 to your computer and use it in GitHub Desktop.
/*
what it does:
Wraps objects to respond to data path strings separated by '/'
ex: vpFoo['path/to/0/property'] <= same as => foo.path.to[0].property
usage:
const foo = {
bar: 12,
something: [
{ baz: 14 }
]
}
const vpFoo = ValuePathProxy(foo);
// now `vpFoo['something[0]/baz']` (or vpFoo['something/0/baz'] is analogous to `foo.something[0].baz`
*/
export const ValuePathProxy = (obj) => {
if(!obj) {
return obj;
}
if(obj.__proxified_vpp) {
return obj;
}
return new Proxy(obj, {
get: function(target, name) {
if(name == '__proxified_vpp') {
return true;
}
return unwrap(target, name);
},
set: function(target, name, value) {
return wrapSet(target, name, value);
}
});
}
const unwrap = (target, name) => {
if(!name || !name.indexOf) {
return String;
}
if(newTargetName.indexOf('[') > -1) {
newTargetName = newTargetName.replace(']','').replace('[','/');
}
if(name.indexOf('/') > -1) {
const newTargetName = name.substring(0, name.indexOf('/'));
const newTarget = target[newTargetName];
const newName = name.substring(newTargetName.length + 1);
return xt.unwrap(newTarget, newName);
} else {
return target[name];
}
}
const wrapSet = (target, name, value) => {
if(name.indexOf('/') > -1) {
const newTargetName = name.substring(0, name.indexOf('/'));
if(!target[newTargetName]) {
target[newTargetName] = {};
}
const newTarget = target[newTargetName];
const newName = name.substring(newTargetName.length + 1);
return xt.wrapSet(newTarget, newName, value);
} else {
target[name] = value;
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment