1

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.

4 Answers 4

2

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

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

1 Comment

tx U ... perfect!
2

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.

1 Comment

the structure fluctuates because fluent validation is used.. and depending on the child object it creates messages for each different object. In this case only Message, and ModelState are known... not account.Contact.PrimaryPhone for example
0
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));

Comments

0

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), [])

2 Comments

This won't flatten the inner arrays.
You're right. I forgot to spread next. Updated accordingly.

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.