/ #JavaScript #web development 

Avoid null/undefined in JavaScript arrays

How to avoid TypeError: Cannot read property ___ of undefined using Array.filter(Boolean)

tl;dr: Array.filter(Boolean) filters out falsy values (null, undefined, 0, false, '') and avoids Cannot read property of undefined errors.

Table of contents:

Table of Contents

This was originally posted on 11th of April 2018, as the first post of the Code with Hugo blog

The original version is available on dev.to/hugo__df/avoiding-falsy-values-in-javascript-arrays

EDITS:

  • 13th December 2018 to improve readability and reach a wider audience.

An overview of the “Boolean” function/constructor

Boolean when passed any falsy value returns false and when passed a truthy value returns true, see the following:

Boolean(false); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(0); // false
Boolean(NaN); // false

Boolean(1); // true
Boolean("hello"); // true
Boolean(true); // true
Boolean({}); // true
Boolean([]); // true

A simple example of .filter(Boolean)

// Fun function that converts a name into a
// 4 all-cap letters display name
const makeDisplayName = name =>
  (name.charAt(0) + name.slice(1).replace(/a|e|i|o|u/g, ""))
    .toUpperCase()
    .slice(0, 4);

const displayNames = [null, "orange", "apple", "mango", undefined]
  .filter(Boolean)
  .map(makeDisplayName);
// [ 'ORNG', 'APPL', 'MNG' ]

// vs
const displayNamesErrors = [null, "orange", "apple", "mango", undefined].map(
  makeDisplayName
);
// TypeError: Cannot read property 'charAt' of undefined

How this works & caveats

Note that a valid use case of filtering out falsy values except 0 needs special treatment since, Boolean(0) returns false, hence:

const noFalsyEvenZero = [NaN, undefined, null, 0, 1, 2, 2000, Infinity].filter(
  Boolean
);
// [ 1, 2, 2000, Infinity ]
const noFalsyExceptZero = [
  NaN,
  undefined,
  null,
  0,
  1,
  2,
  2000,
  Infinity
].filter(el => el === 0 || Boolean(el));
// [ 0, 1, 2, 2000, Infinity ]

Situations in which “Cannot read property of undefined” would this occur

Usually this happens when you want to compute something over an Array of objects where some of the elements have a property but others don’t.

const companies = [
  {
    name: null,
    employees: [],
    founders: []
  },
  {
    name: "orange",
    employees: [],
    founders: []
  },
  {
    name: "apple",
    employees: [],
    founders: []
  },
  {
    name: "mango",
    employees: [],
    locations: []
  },
  {
    employees: [],
    founders: []
  }
];
const companyNames = companies.map(company => company.name);
// [undefined, "orange", "apple", "mango", undefined]

An issue can occur when you have null or undefined in your list

const makeDisplayName = name =>
  (name.charAt(0) + name.slice(1).replace(/a|e|i|o|u/g, ""))
    .toUpperCase()
    .slice(0, 4);

const companyDisplayNames = [null, "orange", "apple", "mango", undefined].map(
  makeDisplayName
);
// TypeError: Cannot read property 'charAt' of undefined

To avoid this we can filter falsy values out:

const makeDisplayName = name =>
  (name.charAt(0) + name.slice(1).replace(/a|e|i|o|u/g, ""))
    .toUpperCase()
    .slice(0, 4);

const companyDisplayNames = [null, "orange", "apple", "mango", undefined]
  .filter(Boolean) // the identity function: `item => item` would also work here :)
  .map(makeDisplayName);
// [ 'ORNG', 'APPL', 'MNG' ]
// No Error :)

Looking for a new job? Take Triplebyte’s quiz and have top tech companies pitch you!

Author

Hugo Di Francesco

A Software Engineer who is big on Node.js, queues and Vue(s). Co-author of "Professional JavaScript" with Packt. He shares practical JavaScript tips for the developer who wants to get things done on Code with Hugo. University College London (UCL), MEng Mathematical Computation Graduate.

Get Testing Superpowers with these Underused Jest Features

Subscribe for free resources that turbocharge your Jest tests and a discount on the "Advanced Jest Handbook"