DEV Community

Cover image for Avoiding falsy values in JavaScript arrays
Hugo Di Francesco
Hugo Di Francesco

Posted on • Originally published at codewithhugo.com on

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 ]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 :)
Enter fullscreen mode Exit fullscreen mode

Originally published at codewithhugo.com on April 11, 2018.

Top comments (0)