0

I am getting the following object from API call:

{
    "email": ["The email has already been taken."],
    "profile_image": [ "profile image is requried." ]
}

I used the following code to iterate over this object (using for...of):

let message = "";
for (const [error_name, error_value, i] of Object.entries(
  error.response.data.errors
)) {
  message += `${i}: ${error_value[0]}\n`;
}

But I am getting undefined instead of getting the value of i. I want to get the iteration number.

Any suggestions?

ok.
  • 65
  • 8

2 Answers2

4

An Object.entries item will only contain two values: the key and the value. If you want the index as well, you'll have to implement it yourself or use another strategy. One option is use forEach to iterate over the array instead (the second argument forEach takes is the current index):

let message = "";
Object.entries(error.response.data.errors)
  .forEach(([error_name, error_value], i) => {
    message += `${i}: ${error_value[0]}\n`;
  });

You can also avoid the let for message by using .map/.join:

const message = Object.entries(error.response.data.errors)
  .map(([error_name, error_value], i) => `${i}: ${error_value[0]}`)
  .join('\n');

(unlike your original code, this will not have a trailing newline at the end, but that's probably a good thing)

CertainPerformance
  • 260,466
  • 31
  • 181
  • 209
  • Bro can you tell me if there is only 1 element in the object then don't display `${i}:` part. – ok. Jul 31 '19 at 14:22
  • I'd save the entries in a variable and use the conditional operator. `const message = errorEntries.length === 1 ? errorEntries[1] : entries.map(...code in answer...)` – CertainPerformance Jul 31 '19 at 19:55
  • Bro the 3rd param is the obj which get passed I wrote, `const message = Object.entries(error.response.data.errors) .map(([error_name, error_value], index, obj) => Object.keys(obj).length == 1 ? ${error_value[0]} : ${index + 1}: ${error_value[0]} ) .join("\n");` – ok. Aug 01 '19 at 06:41
  • Much better to save the entries in a variable first, rather than to try to stuff it all into a single assignment expression – CertainPerformance Aug 01 '19 at 06:45
0

The iterator from Object.entries only produces two-place arrays in the form [key, value]. There is no third entry in those arrays.

In general, objects should be considered unordered, so it's not clear why you want an index. But if you do, since you're building a string with concatenation, you could use map on the Object.entries array instead:

let message =
    Object.entries(error.response.data.errors)
    .map(([error_name, error_value], i) => `${i}: ${error_value[0]}\n`)
    .join("");

Live Example:

const error = {
    response: {
        data: {
            errors: {
              "email": ["The email has already been taken."],
              "profile_image": [ "profile image is requried." ]
            }
        }
    }
};
let message =
    Object.entries(error.response.data.errors)
    .map(([error_name, error_value], i) => `${i}: ${error_value[0]}\n`)
    .join("");
console.log(message);
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639