I have this JSON from Mongoose error catching on a NodeJS app with the express framework:
{
"err": {
"errors": {
"last_name": {
"message": "Path `last_name` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `last_name` is required.",
"type": "required",
"path": "last_name"
},
"kind": "required",
"path": "last_name"
},
"first_name": {
"message": "Path `first_name` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `first_name` is required.",
"type": "required",
"path": "first_name"
},
"kind": "required",
"path": "first_name"
},
"password": {
"message": "Path `password` (`iam`) is shorter than the minimum allowed length (6).",
"name": "ValidatorError",
"properties": {
"message": "Path `password` (`iam`) is shorter than the minimum allowed length (6).",
"type": "minlength",
"minlength": 6,
"path": "password",
"value": "iam"
},
"kind": "minlength",
"path": "password",
"value": "iam"
}
},
"_message": "User validation failed",
"message": "User validation failed: last_name: Path `last_name` is required., first_name: Path `first_name` is required., password: Path `password` (`iam`) is shorter than the minimum allowed length (6).",
"name": "ValidationError"
}
}
How can I get the type and path of each error inside the properties, I have tried forEach() method but it didn't work, is there any other way to loop through this JSON?
Shidersz
17.2k2 gold badges28 silver badges52 bronze badges
asked May 19, 2019 at 18:04
Kadiem Alqazzaz
6791 gold badge10 silver badges31 bronze badges
-
You can browse with Object.keys().Antoine Olivier– Antoine Olivier2019年05月19日 18:12:00 +00:00Commented May 19, 2019 at 18:12
-
Possible duplicate of How do I loop through or enumerate a JavaScript object?kgrg– kgrg2019年05月19日 19:38:48 +00:00Commented May 19, 2019 at 19:38
2 Answers 2
Find the keys, the iterate over the keys. Add those results to some data structure.
I've chose to use map on the keys and added to an array.
const errors = {
"err": {
"errors": {
"last_name": {
"message": "Path `last_name` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `last_name` is required.",
"type": "required",
"path": "last_name"
},
"kind": "required",
"path": "last_name"
},
"first_name": {
"message": "Path `first_name` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `first_name` is required.",
"type": "required",
"path": "first_name"
},
"kind": "required",
"path": "first_name"
},
"password": {
"message": "Path `password` (`iam`) is shorter than the minimum allowed length (6).",
"name": "ValidatorError",
"properties": {
"message": "Path `password` (`iam`) is shorter than the minimum allowed length (6).",
"type": "minlength",
"minlength": 6,
"path": "password",
"value": "iam"
},
"kind": "minlength",
"path": "password",
"value": "iam"
}
},
"_message": "User validation failed",
"message": "User validation failed: last_name: Path `last_name` is required., first_name: Path `first_name` is required., password: Path `password` (`iam`) is shorter than the minimum allowed length (6).",
"name": "ValidationError"
}
}
let output = Object.keys(errors.err.errors).map(key => { return {type:errors.err.errors[key].properties.type, path:errors.err.errors[key].properties.path} });
console.log(output);
answered May 19, 2019 at 18:12
Randy Casburn
14.2k1 gold badge20 silver badges32 bronze badges
Sign up to request clarification or add additional context in comments.
2 Comments
some
map returns an array. You do not need to first create output =[] and then pushing in the function. Just do let output=Object.keys(errors.err.errors).map(key =>({type:errors.err.errors[key].properties.type, path:errors.err.errors[key].properties.path})). If you don't want the array, use forEach instead to iterate over the array.some
You don't need to use
return in the arrow-function, but since you are returning an object you must enclose it in parentheses (or it will be interpreted as a statement). key => ({type:"error"}) works, key => {type:"error"} doesn't, key => {return {type:"error"}} works but is longer to type..Another alternative is to use for ... in to traverse the object properties of err.errors:
Example:
const input = {"err":{"errors":{"last_name":{"message":"Path `last_name` is required.","name":"ValidatorError","properties":{"message":"Path `last_name` is required.","type":"required","path":"last_name"},"kind":"required","path":"last_name"},"first_name":{"message":"Path `first_name` is required.","name":"ValidatorError","properties":{"message":"Path `first_name` is required.","type":"required","path":"first_name"},"kind":"required","path":"first_name"},"password":{"message":"Path `password` (`iam`) is shorter than the minimum allowed length (6).","name":"ValidatorError","properties":{"message":"Path `password` (`iam`) is shorter than the minimum allowed length (6).","type":"minlength","minlength":6,"path":"password","value":"iam"},"kind":"minlength","path":"password","value":"iam"}},"_message":"User validation failed","message":"User validation failed: last_name: Path `last_name` is required., first_name: Path `first_name` is required., password: Path `password` (`iam`) is shorter than the minimum allowed length (6).","name":"ValidationError"}};
for (const k in input.err.errors)
{
const properties = input.err.errors[k].properties;
console.log("Error for " + k);
console.log("> Type: " + properties.type);
console.log("> Path: " + properties.path);
console.log("> Message: " + properties.message);
}
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
answered May 19, 2019 at 18:44
Shidersz
17.2k2 gold badges28 silver badges52 bronze badges
5 Comments
Shidersz
@some But, to use
for ... of I will have to do something like for (k of Object.keys(input.err.errors)) since it won't work directly over the object. And in this case, whit an array of keys, I will prefer to use built-in array methods like shown on the other answer.some
Use
for (const [key,value] of Object.entries(input.err.errors)) and instead of making lookups in input.err.errors[k] every time, use the variables key or value (or what you called them)Shidersz
@some Ok, it is another alternative, but not what I have tried to show. I just tried to show how to traverse some object directly, not converting first to an array of
keys or entries.some
Look at your code. You use
input.err.errors[k] twice. And you would have used it three times if you also printed the message. Every time you do input.err.errors[k] you make a lookup. At least save that as a constant for each iteration. const value = input.err.errors[k] instead of making the exact same lookup multiple times. It is not premature optimization. It is less to type, less chance to make a typo, easier to change if the path changes.lang-js