0

I have a Javascript object which looks as below. I want to iterate through the object and find out values for the Hostnames

const data =
{
  "error1": {
    "7": [
      {
        "ErrorType": "Error-1A",
        "Hostnames": "host123.com,hostabc.com,host33a.com..."
      }
    ],
    "8": [
      {
        "ErrorType": "Error-1B",
        "Hostnames": "host223.com,host2c.com,host43a.com..."
      },
      {
        "ErrorType": "Error-1C",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ]
  },
  "error2": {
    "3": [
      {
        "ErrorType": "Error-2A"
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      },
      {
        "ErrorType": "Error-2B"
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ],
    "8": [
      {
        "ErrorType": "Error-2C"
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      },
      {
        "ErrorType": "Error-2D",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ]
  },
  "error3": {
    "1": [
      {
        "ErrorType": "Error-3A",
        "Hostnames": "host1236.com"
      },
      {
        "ErrorType": "Error-3B",
        "Hostnames": "hostc3231.com"
      }
    ]
  }
}

I have written following NodeJS function:

const findObjectByLabel = function(obj, label) {
    if(obj.label === label) { return obj; }
    for(var i in obj) {
        if(obj.hasOwnProperty(i)){
            var foundLabel = findObjectByLabel(obj[i], label);
            if(foundLabel) { return foundLabel; }
        }
    }
    return null;
};

const hostNames = findObjectByLabel(data, 'Hostnames');
console.log(hostNames);

The above function is throwing an error:

Error: undefined : RangeError: Maximum call stack size exceeded

2 Answers 2

3

So let's remove useless context. You want to find 'Hostnames' values in an Object, deeply.

And your recursion seems to loop, causing maximul call stack size exceeded error.

How can you find the problem by yourself? Just add `console.log('ON', obj) as first line of your 'findObjectByLabel' function.

You will see that you loop on 'E'. Because at some point, the tested object is a string.

Second problem: You check for .label === 'Hostnames'... there is no 'label' key in your json data.

Another problem after this one fixed is that you'll stop on the first hostname.

Here is a solution

function deepFind(obj, label, results=[]) {
    if( typeof obj !== 'object' && !!obj )
      return null;

    if( !!obj[label] ) {
      results.push(obj[label]);
    }

    Object.getOwnPropertyNames(obj).forEach( k => {
      deepFind(obj[k], label, results);
    });
}

const results = [];
deepFind(data, 'Hostnames', results);

Not elegant but it works

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

Comments

2

Data structure requires nested loops, but this works. This will provide an array of hostnames per this: "I want to iterate through the object and find out values for the Hostnames".

const data = {
  "error1": {
    "7": [{
      "ErrorType": "Error-1A",
      "Hostnames": "host123.com,hostabc.com,host33a.com..."
    }],
    "8": [{
        "ErrorType": "Error-1B",
        "Hostnames": "host223.com,host2c.com,host43a.com..."
      },
      {
        "ErrorType": "Error-1C",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ]
  },
  "error2": {
    "3": [{
        "ErrorType": "Error-2A",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      },
      {
        "ErrorType": "Error-2B",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ],
    "8": [{
        "ErrorType": "Error-2C",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      },
      {
        "ErrorType": "Error-2D",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ]
  },
  "error3": {
    "1": [{
        "ErrorType": "Error-3A",
        "Hostnames": "host1236.com"
      },
      {
        "ErrorType": "Error-3B",
        "Hostnames": "hostc3231.com"
      }
    ]
  }
};

const out = [];
for (let key in data) {
  for (let number in data[key]) {
    data[key][number].map(d => out.push(d.Hostnames));
  }
}

console.log(out);

Comments

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.