Swizec Teller - a geek with a hatswizec.com

    Javascript debugging [slightly] beyond console.log


    My favourite tool for javascript debugging is console.log.

    I mean, I love console.log. If I ever get a programming tattoo, it's going to be console.log or some variation thereof. Simple to use, works every time, and every programming language I've used since I was 9 has had some variation of it.

    Swizec Teller published ServerlessHandbook.dev avatarSwizec Teller published ServerlessHandbook.dev@Swizec
    console.log forever

    been coding for 20 years and it's still the best

    Pascal acting up? Not sure what's going on? writeln

    Python being silly? print

    C acting funny? printf

    CSS weird? border: 1px solid red

    HTML messing with you? Nah, Chrome's element inspector.

    But as much as I love console.log, sometimes it just does not do. Sure, if you have a proper test suite console.log is always enough. But you don't always have a proper test suite.

    Let me explain.

    When you want to understand what's going on and where exactly a piece of code goes wrong, you do something like this.

    var do_something = function (arg1) {
    console.log("got into function", arg1);
    var foo = get_my_foo(arg1);
    console.log("foo changed?", foo);
    return foo;

    Not the prettiest. But it works. You can tell what's going on.

    You know for certain the function was called, what the argument value was, and you know the value of foo when it returns.

    Perfect for calling the code once. But what if it's part of a list building mechanism?

    a_lot_of_things.map(function (thing) {
    var label = do_something(thing);

    Wellp, now you've got a bunch of console output to look through. Annoying, but manageable. You can still tell which argument produces which output.

    But we're stretching the limits of console.log here.

    Now what if somebody does this?

    async.map(a_lot_of_things, function (thing) {
    var label = do_something(thing);

    Wow, that's annoying. Your do_something function is called asynchronously. The output is all jumbled up!

    Very annoying. But you can map input to output in your mind. They're both printed right next to each other.

    It's just harder because you have to read the whole output every time and can't jump to the line you're interested in. The problem is ALWAYS with just one of the elements. Obviously.

    Wow, we're really stretching that console.log. Let's break it.

    var do_something = function (arg1, callback) {
    console.log("got into function", arg1);
    var foo = get_my_foo(arg1);
    setTimeout(function () {
    console.log("foo changed?", foo);
    }, 100);
    async.map(a_lot_of_things, function (thing) {
    do_something(thing, function (label) {

    You wouldn't just spray setTimeouts in your code like that. But now you have an asynchronous function. Maybe it's an Angular watch, you're responding to a promise, or something.

    Point is, all of your console.log outputs are now jumbled up and useless. Something like this:

    got into function, foo1 got into function, foo3 foo changed?, yes got into
    function, foo2 foo changed?, no got into function, foo4 got into function, foo5
    foo changed?, yes foo changed?, no foo changed?, yes

    Wow, talk about useless!

    When faced with a situation like this, I would start adding alert()s to my code. It stops execution and lets you look at the output in a particular moment.

    But it blocks the entire browser, you can't look around much, and clicking all those pop ups is annoying as hell. Especially once you've found the culprit, but can't just refresh the page.

    alert() disables Cmd+R because it steals focus from the window. You have to get to the end of the loop before you can stop it.


    A few weeks ago I stumbled onto a better way through someone's throwaway comment. debugger;

    It. Is. Magic.

    Instead of that second print statement, console.log("foo changed?", foo), we'd put debugger;. When Chrome, and other modern browsers?, sees that statement, it stops.

    But it doesn't just stop. It gives you a debugger.

    The debugger, initial view
    The debugger, initial view

    You can't see it in the screenshot, but even GIFs are stopped. A moment ago that Santa was dancing, now everything is in "Holy shit, he's debugging!" mode.

    The code that triggered debugger; is in the middle. A bunch of inspection tools are on the right. On top of the screen is an "I'm done now, please continue" button.

    But more importantly, the console is in current scope! You can do whatever you want.

    Console is in current scope
    Console is in current scope

    And once you've found the culprit, you can just refresh the page. No waiting for all the alert()s to show up.

    Now, I'm not going to stop using console.log any time soon. But knowing about debugger has made my life easier many times.

    I only wish I'd known about it sooner.

    Did you enjoy this article?

    Published on January 14th, 2015 in Frontend Web, JavaScript, Technical

    Learned something new?
    Want to become an expert?

    Here's how it works 👇

    Leave your email and I'll send you thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

    Join Swizec's Newsletter

    And get thoughtful letters 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.

    "Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"

    ~ Ashish Kumar

    Join over 14,000 engineers just like you already improving their careers with my letters, workshops, courses, and talks. ✌️

    Have a burning question that you think I can answer? I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

    Ready to Stop copy pasting D3 examples and create data visualizations of your own?  Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

    Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

    Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first 💰 on the side with ServerlessReact.Dev

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️