Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
Debugging is the process of finding and fixing errors in your code. Master console methods, breakpoints, and browser DevTools to become a debugging ninja!
console.table() instead of console.log(). It displays data in an easy-to-read table format, making it much faster to spot issues in your data.Use the %c directive to apply CSS styles to console messages:
Format console messages with placeholders:
%s - String value%d or %i - Integer value%f - Floating-point value%o - Object with expandable properties%O - Object with generic JavaScript representationControl when logs appear in production:
// Adding logs everywhere
function calculateTotal(items) {
console.log('Items:', items);
let total = 0;
console.log('Initial total:', total);
for (const item of items) {
console.log('Processing:', item);
total += item.price;
console.log('Running total:', total);
}
console.log('Final total:', total);
return total;
}
// Logs clutter output
// Hard to track flow
// Must remove logs later// Pause execution at specific point
function calculateTotal(items) {
debugger; // βΈοΈ Execution pauses here
let total = 0;
for (const item of items) {
total += item.price;
}
return total;
}
// When debugger hits:
// - Inspect all variables
// - Step through code line by line
// - See call stack
// - No need to remove later!Conditional Breakpoints: Pause only when a condition is true (e.g., when a variable equals a specific value)
Logpoints: Log messages without pausing execution - like console.log but temporary
DOM Breakpoints: Pause when an element is modified, attributes change, or element is removed
// Error: Cannot read property 'name' of undefined
// at line 45 in user.js
// What it tells you:
// 1. What went wrong: trying to access .name
// 2. On what: undefined object
// 3. Where: line 45 in user.js
// Action: Check if user exists before accessing
if (user && user.name) {
console.log(user.name);
}// Bug somewhere in this chain
const result = fetchData()
.then(processData)
.then(validateData)
.then(saveData);
// Add logs to narrow down
const result = fetchData()
.then(data => {
console.log('1. Fetched:', data);
return processData(data);
})
.then(data => {
console.log('2. Processed:', data);
return validateData(data);
})
.then(data => {
console.log('3. Validated:', data);
return saveData(data);
});
// Find which step failsExplain your code to a rubber duck (or colleague):
"This function should fetch user data, then..."
"Wait... I'm assuming the data exists, but what if it's null?"
"Ah! That's the bug!"
π¦ Often, explaining the problem reveals the solution!
// Assumption: API returns array
const users = await fetchUsers();
users.map(u => u.name); // Error!
// Verify assumption
console.log('Type:', typeof users);
console.log('Is array?', Array.isArray(users));
console.log('Value:', users);
// Reality: API returned object with 'data' property
const users = (await fetchUsers()).data;
users.map(u => u.name); // Works!Find exact steps to reproduce:
1. Open app in incognito mode
2. Login as test user
3. Click "Edit Profile"
4. Change email to invalid format
5. Click Save β Bug appears!
π― Reproducible bugs are much easier to fix!
log, error, warn, table, group
time, count, assert, trace
Style output with %c
debugger statement
DevTools breakpoints
Step through code line by line
Read error messages
Divide and conquer
Check assumptions, reproduce bugs
console.time() for timing
DevTools Performance tab
Lighthouse audits