user1161137
user1161137

Reputation: 1117

How to get all properties values of a Javascript Nested Objects (without knowing the keys)?

In referencing how to do this i took a look at how-to-get-all-properties-values-of-a-javascript-object-without-knowing-the-key Using ES6

How would you do this if the object you are scanning into has child object where you need only the Values for those too, into an array.

example :

var errorData = {"Message":"The request is invalid.","ModelState":{"account.Contact.PrimaryPhone":["Primary Phone is required.","'Primary Phone' should not be empty."]}}

var errors = Object.keys(errorData).map(function (key) {
      return errorData[key];
});

doesn't work.

i need an array that lists like this:

The request is invalid.
Primary Phone is required.
'Primary Phone' should not be empty.

Upvotes: 1

Views: 758

Answers (4)

sellmeadog
sellmeadog

Reputation: 7517

This should work. Just through it together, haven't fully tested it.

Object.values(a)
  .map(v => v instanceof Object ? Object.values(v) : [v])
  .reduce((acc, next) => acc.concat(...next), [])

Upvotes: 0

Dan Nagle
Dan Nagle

Reputation: 5425

let errorData = {"Message":"The request is invalid.","ModelState":{"account.Contact.PrimaryPhone":["Primary Phone is required.","'Primary Phone' should not be empty."]}}

const flatten = (obj) => obj.reduce((acc, val) => acc.concat(val), []);

const unwrap = (obj) => 
    Object.keys(obj).map((key) => { 
        if (typeof(obj[key]) == 'object') 
            return flatten(unwrap(obj[key]));
        else
            return obj[key];
    });

let errors = flatten(unwrap(errorData));

Upvotes: 0

Paul
Paul

Reputation: 141827

The easiest way is probably with a recursive function. You can do that like this in a modern engine:

const errorData = {"Message":"The request is invalid.","ModelState":{"account.Contact.PrimaryPhone":["Primary Phone is required.","'Primary Phone' should not be empty."]}}

const errors = (function flattenValues( obj ) {
  return Object.values( obj ).reduce(
    ( values, value ) => values.concat( typeof value === "object" ? flattenValues( value ) : value )
  , [ ] );
} )( errorData );

console.log( errors );

although Object.values only has fairly recent browser support, so you may want to use something that has more compatibility instead:

var errorData = {"Message":"The request is invalid.","ModelState":{"account.Contact.PrimaryPhone":["Primary Phone is required.","'Primary Phone' should not be empty."]}}

var errors = (function flattenValues( obj ) {
  return Object.keys( obj ).reduce( function ( keys, key ) {
    var value = obj[key];
    return values.concat( typeof value === "object" ? flattenValues( value ) : value );
  }, [ ] );
} )( errorData );

console.log( errors );

Upvotes: 2

Abderrahmane TAHRI JOUTI
Abderrahmane TAHRI JOUTI

Reputation: 4273

There usually is a fixed structure to an API response, or at least a certain guideline. You could test for the type of the value, and see if it is an array or object. You could also anticipate a particular key in the response, test for its existence, and do work accordingly.

Upvotes: 2

Related Questions