Lập trình · 26/09/2026

JavaScript Array.isArray: Validate API Data Before Calling map

An “items.map is not a function” error often leads to an empty-array fallback. But turning a malformed API response into [] can make users believe their data does not exist. Separate array detection, element validation and error presentation.

JavaScript Array.isArray: Kiểm tra dữ liệu API trước khi gọi map

An “items.map is not a function” error often leads to an empty-array fallback. But turning a malformed API response into [] can make users believe their data does not exist. Separate array detection, element validation and error presentation.

1. Use the right array check

console.log(Array.isArray([])); // true
console.log(Array.isArray({ length: 0 })); // false
console.log(Array.isArray(null)); // false
console.log(Array.isArray('[]')); // false

The MDN Array.isArray reference documents checking whether a value is an Array. A length property or list-like log output is insufficient. The string '[]' is still a string.

After JSON.parse or response.json, inspect the resulting value rather than decoding it again blindly. Valid JSON can represent an object, null or a scalar instead of a list.

2. Validate elements against a contract

Suppose the response is an object with an items array. Each record requires a positive safe-integer id and a name string that is nonblank after trimming. This is an example contract; string identifiers require different rules.

function readItems(payload) {
  if (payload === null || typeof payload !== 'object'
      || Array.isArray(payload) || !Array.isArray(payload.items)) {
    throw new TypeError('Expected an object with an items array');
  }

  const result = [];
  for (const item of payload.items) {
    if (item === null || typeof item !== 'object'
        || Array.isArray(item)
        || !Number.isSafeInteger(item.id) || item.id <= 0
        || typeof item.name !== 'string' || item.name.trim() === '') {
      throw new TypeError('Invalid item');
    }
    result.push({ id: item.id, name: item.name });
  }
  return result;
}

This function targets decoded JSON, not arbitrary JavaScript objects. It produces records containing only id and name. It does not silently discard invalid entries, check duplicate IDs or trim returned names. Make those choices explicit in production.

3. Empty is different from unreadable

Under this contract, {items: []} is valid and empty. {items: null}, {} and {items: {}} are invalid. Converting all of them into [] removes the distinction between no records and a failure to load records.

Provide a separate error state so users know to retry or seek support. Log minimal diagnostic context rather than complete responses containing personal information. Shape validation also does not replace HTTP-status checks or network-error handling.

4. Validation is not sanitization

A type-valid name can still contain HTML characters. Render it as text with appropriate escaping; passing readItems is not permission to insert it into innerHTML.

Frontend validation detects integration defects and protects interface behavior. It does not grant authorization, replace backend enforcement or establish business correctness.

5. Test cases

  • {items: []} returns an empty array.
  • A valid record returns its id and name.
  • Missing items, null and object values throw.
  • Null entries, missing names and string IDs are rejected.
  • One invalid entry does not silently produce partial success.
  • The interface distinguishes empty and failed results.

The goal is not an Array.isArray check on every line. Validate at the application boundary, produce a stable internal structure and preserve errors instead of concealing them with defaults.

Discussion

Comments 0

Sign in to comment

You need an account to join the discussion and reply to other readers.

Sign inRegister

No comments yet. Be the first to share your thoughts.