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
3
  • 1
    this [cat.id].aggs is your own custom format so you will need your own parser to read it and traverse object accordingly Commented May 25, 2020 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 Commented May 25, 2020 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. Commented May 25, 2020 at 14:26

1 Answer 1

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));

Sign up to request clarification or add additional context in comments.

3 Comments

Problem is I just don't need to access the attribute, I need to assign a new value to that attribute as well.
Thanks trincot, it works for the first level but fails when there is more inner levels like [cat.id].aggs[cat.label].aggs
Applied a fix near the end of the regular expression.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.