JavaScript Debugging Utilities for Undefined Function Errors
Ready-to-use JavaScript debugging utilities and code examples to fix and prevent 'undefined is not a function' errors with practical implementation.
JavaScript Debugging Utilities for Undefined Function Errors
When debugging "undefined is not a function" JavaScript errors, having the right utility functions can save you hours of troubleshooting. This collection provides ready-to-use debugging utilities and prevention code to quickly identify and fix these common errors.
Core Debugging Utilities #
1. Safe Function Caller #
A utility that safely executes functions with built-in error handling:
2. Object Method Validator #
Validate object methods before calling them:
3. Function Existence Checker #
Utility to check if functions exist in different scopes:
// Function existence checker for global, window, and object scopes
function checkFunctionExists(functionPath, scope = window) {
const parts = functionPath.split('.');
let current = scope;
const path = [];
console.log('🔍 Checking function path:', functionPath);
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
path.push(part);
if (current === null || current === undefined) {
console.error(`❌ Path broken at: ${path.join('.')} - parent is ${current}`);
return {
exists: false,
brokenAt: path.join('.'),
reason: 'Parent object is null/undefined'
};
}
if (!(part in current)) {
console.error(`❌ Property '${part}' not found in:`, current);
console.log('Available properties:', Object.keys(current));
return {
exists: false,
brokenAt: path.join('.'),
reason: 'Property not found',
available: Object.keys(current)
};
}
current = current[part];
console.log(`✓ Found: ${path.join('.')} (type: ${typeof current})`);
}
const isFunction = typeof current === 'function';
console.log(`${isFunction ? '✅' : '❌'} Final check: ${functionPath} is ${isFunction ? '' : 'not '}a function`);
return {
exists: true,
isFunction,
value: current,
type: typeof current
};
}
// Example usage
const testObj = {
api: {
users: {
get: function(id) { return `User ${id}`; },
list: function() { return ['User1', 'User2']; }
}
}
};
// Test existing function
checkFunctionExists('api.users.get', testObj);
// Test non-existing function
checkFunctionExists('api.posts.create', testObj);
4. Async Function Waiter #
Wait for functions to become available in async environments:
5. Module Import Debugger #
Debug module import/export issues:
// Module import debugging utility
function debugModuleImport(modulePath, expectedExports = []) {
console.log('🔍 Debugging module import:', modulePath);
try {
const module = require(modulePath); // For Node.js
// For ES modules, this would be handled differently
console.log('✅ Module loaded successfully');
console.log('Module type:', typeof module);
console.log('Module keys:', Object.keys(module));
// Check expected exports
const missing = [];
const found = [];
expectedExports.forEach(exportName => {
if (exportName in module) {
found.push({
name: exportName,
type: typeof module[exportName],
isFunction: typeof module[exportName] === 'function'
});
} else {
missing.push(exportName);
}
});
if (found.length > 0) {
console.log('✅ Found exports:', found);
}
if (missing.length > 0) {
console.error('❌ Missing exports:', missing);
}
return {
success: true,
module,
found,
missing,
available: Object.keys(module)
};
} catch (error) {
console.error('❌ Module import failed:', error.message);
return {
success: false,
error: error.message
};
}
}
// Example usage
debugModuleImport('./math-utils', ['add', 'subtract', 'multiply']);
Error Prevention Patterns #
6. Default Function Provider #
Provide fallback functions to prevent undefined errors:
7. Function Chain Validator #
Validate entire function call chains:
// Function chain validator
function validateChain(obj, chain) {
console.log('🔍 Validating chain:', chain);
const parts = chain.split('.');
let current = obj;
const validatedPath = [];
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
validatedPath.push(part);
const currentPath = validatedPath.join('.');
if (current === null || current === undefined) {
return {
valid: false,
error: `Chain broken at '${currentPath}': parent is ${current}`,
validUpTo: validatedPath.slice(0, -1).join('.')
};
}
if (!(part in current)) {
return {
valid: false,
error: `Property '${part}' not found in '${validatedPath.slice(0, -1).join('.')}'`,
available: Object.keys(current),
validUpTo: validatedPath.slice(0, -1).join('.')
};
}
current = current[part];
// If this is the last part, check if it's a function
if (i === parts.length - 1) {
const isFunction = typeof current === 'function';
return {
valid: isFunction,
isFunction,
finalType: typeof current,
value: current,
error: isFunction ? null : `Final property '${part}' is not a function (${typeof current})`
};
}
}
}
// Example usage with complex object
const complexObj = {
api: {
v1: {
users: {
get: function(id) { return `User ${id}`; },
create: function(data) { return `Created user`; }
}
}
}
};
console.log(validateChain(complexObj, 'api.v1.users.get'));
console.log(validateChain(complexObj, 'api.v1.posts.create'));
Quick Debug Commands #
Copy these one-liners for quick debugging in browser console:
// Quick function existence check
const exists = (path) => path.split('.').reduce((o,p) => o?.[p], window);
// Quick type check
const typeCheck = (path) => typeof path.split('.').reduce((o,p) => o?.[p], window);
// Quick safe call
const safeFn = (fn, ...args) => typeof fn === 'function' ? fn(...args) : console.error('Not a function:', fn);
// Debug object properties
const debugObj = (obj) => ({ keys: Object.keys(obj), types: Object.keys(obj).map(k => [k, typeof obj[k]]) });
Summary #
These debugging utilities provide a comprehensive toolkit for handling "undefined is not a function" errors in JavaScript. Use safeCall()
for immediate protection, validateAndCall()
for object methods, and waitForFunction()
for async scenarios. The prevention patterns help build more robust applications that gracefully handle missing functions.
Copy and customize these utilities for your specific debugging needs, and always validate function existence before calling them in production code.