/ #JavaScript #web development 

Avoiding falsy values in JavaScript arrays

tl;dr: use Array.filter(Boolean) to filter out falsy values and avoid errors.

// 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

Boolean when passed any falsy value returns false and when passed a truthy value returns true:

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

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 this 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 :)
Author

Hugo Di Francesco

A developer, working out of London writing CSS, JavaScript and Python.