1

Suppose I have an object

const aggs = {
      cat.id: {
        terms: { field: 'cat.id', size: 10 },
        aggs: { cat.label: {field: 'cat.label', size: 5} }
      }
    }

In the dynamic variable I have

const key = '[cat.id].aggs'

Now I need to access the attribute aggs inside aggs object using dynamic variable

aggs[key]

which is not working, How can I access the nested attributes dynamically? Obviously accessing it directly like this works

aggs['cat.id'].aggs
vicky shrestha
  • 147
  • 1
  • 11
  • 1
    this `[cat.id].aggs` is your own custom format so you will need your own parser to read it and traverse object accordingly – Max May 25 '20 at 14:19
  • 1
    There are many useful solutions here. You might have to make some minor tweaks: [Accessing nested JavaScript objects and arays by string path](https://stackoverflow.com/questions/6491463) – adiga May 25 '20 at 14:23
  • If you don't use '.' in the keys it becomes easy for you to parse the key. But in a case like this, you might have to write your own parser as there isn't a pattern. – Utkarsh Mehrotra May 25 '20 at 14:26

1 Answers1

1

You can use the usual solutions, but with a specific regular expression that deals appropriately with the brackets, allowing dots in the property names:

const pathToArray = path => 
  Array.from(path.matchAll(/\[(.*?)\]|[^.[]+/g) || [], 
             ([prop, inbrackets]) => inbrackets || prop);

function deepGet(obj, path, defaultVal = null) {
  for (let prop of pathToArray(path)) {
    if (!(prop in obj)) return defaultVal;
    obj = obj[prop];
  }
  return obj;
}

function deepSet(obj, path, value) {
  let arr = pathToArray(path);
  arr.slice(0, -1).reduce((a, c, i) =>
    Object(a[c]) === a[c] ? a[c] :
    a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : {},
    obj)[arr[arr.length - 1]] = value;
  return obj;
}

// Your example:
const aggs = {"cat.id": {terms: {field: "cat.id",size: 10},aggs: {"cat.label": {field: "cat.label",size: 5}}}};
const key = "[cat.id].aggs";

console.log(deepGet(aggs, key));
deepSet(aggs, key, "hello");
console.log(deepGet(aggs, key));
trincot
  • 317,000
  • 35
  • 244
  • 286