Fix the 'is not a function' error in JavaScript

By

Fix the JavaScript TypeError 'is not a function' by checking the value being called, common import and method mistakes, and semicolon edge cases.

~~~

JavaScript throws TypeError: x is not a function when your code tries to call a value that is not callable. Look at the expression immediately before () and inspect what it contains at runtime.

console.log(value)
console.log(typeof value)

If typeof value is not 'function', trace where that value was assigned or imported. The text before is not a function usually points directly to the problem.

Check for a typo or the wrong object

JavaScript method names are case-sensitive:

document.getElementByID('app')
// TypeError: document.getElementByID is not a function

The method is named getElementById, with a lowercase d:

document.getElementById('app')

You also get this error when a method exists, but not on the value you have. map() is an Array method, so this fails:

const user = { name: 'Flavio' }

user.map(value => value)
// TypeError: user.map is not a function

Check the value with Array.isArray() before using Array methods. See my guide to JavaScript arrays for the methods available on arrays.

Check how the function was imported

A default export and a named export use different import syntax. Given this module:

// format.js
export function format(value) {
  return String(value).trim()
}

Import it by name:

import { format } from './format.js'

format(' hello ')

If the import shape does not match the export, you may call the module object or an undefined property instead of the function. You can read more about this in my guide to ES modules.

Also check that you did not overwrite a function with another value:

let format = value => value.trim()

format = 'compact'
format('hello')
// TypeError: format is not a function

Fix $ is not a function

The $ is not a function version means the value stored in $ is not callable in the current scope. Log typeof $ first.

Common causes are a library that did not load, an import that returned a module object instead of its function, or another script that replaced $. Fix how that value is loaded or referenced rather than hiding the error with a type check.

Watch for automatic semicolon insertion

There is one less obvious case when you write JavaScript without semicolons. A line that starts with ( can be parsed as a continuation of the previous expression.

For example, this CommonJS code can throw:

TypeError: require(...) is not a function
const fs = require('fs')

(async () => {
  //...
})()

JavaScript parses it as if you were trying to call the value returned by require('fs'). Add a semicolon before the immediately invoked function expression:

const fs = require('fs')

;(async () => {
  //...
})()

Adding a semicolon to the previous statement also works:

const fs = require('fs');

(async () => {
  //...
})()

If this is an ES module, top-level await may let you remove the async IIFE entirely.

The MDN error reference lists more examples, but the debugging rule is always the same: find the value being called and determine why it is not a function.

Tagged: JavaScript ยท All topics
~~~

Related posts about js: