Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at BFusion / BFLEX 2009 (Bloomington, Indiana) with:

Chrome Dev Tools "Live Update" In The JavaScript Console Is Confusing

Posted by Ben Nadel

Yesterday, I was on a screen share with Ryan Jeffords and Alan Quinlan trying to help debug some JavaScript code. And, like so many developers, we made healthy use of "console.log()" as a means to debug when and where code was going wrong. Only, we were using Chrome as our development browser - not Firefox with Firebug. As such, we got burned by a seriously quirky "live update" feature of the Chrome dev tools.


 
 
 

 
  
 
 
 

I use Firefox with Firebug as my development environment. I know people rave about the Chrome Dev Tools and all its new hawtness; but, to me, Firebug feels like that old tee-shirt you've had around for years - it might not be the lastest and greatest style, but it feels wonderful. As such, I'm not too familiar with behavioral differences between the two development environments. And, as it turns out, there's one very significant and critical difference.

In Firebug, when you log something to the console (in my experience), it remains in the console as a fixed, static value. In Chrome Dev Tools, on the other hand, it seems that complex values, once logged to the output, continue to be "live updated" as the JavaScript runs. To see this in action, take a look the following code:

  • <!doctype html>
  • <html>
  • <head>
  • <meta charset="utf-8" />
  • <title>Chrome Dev Tools Live Console Updates</title>
  •  
  • <script type="text/javascript">
  •  
  •  
  • function getSomeData(){
  •  
  • var data = [
  • "April Ross",
  • "Jennifer Kessy",
  • "Misty May-Treanor",
  • "Kerri Walsh"
  • ];
  •  
  • return( data )
  •  
  • }
  •  
  • function processSomeData( data ){
  •  
  • // Cut out Ross and Kessy - sorry girls!
  • data.splice( 0, 2 );
  •  
  • // Return processed data.
  • return( data );
  •  
  • }
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • var data = getSomeData();
  •  
  • // Log data out for debugging.
  • console.log( data );
  •  
  • // Process the data.
  • processSomeData( data );
  •  
  • // Log the data out again for debugging.
  • console.log( data );
  •  
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Left intentionally blank. -->
  • </body>
  • </html>

As you can see, we're getting some data, then we're processing it. And, to make sure that the data is being processed correctly, I am logged the data both before and after the processing method.

In Firefox with Firebug, we get the following "expected" value in the console:

["April Ross", "Jennifer Kessy", "Misty May-Treanor", "Kerri Walsh"]
["Misty May-Treanor", "Kerri Walsh"]

The data is clearly different in both cases, demonstrating the effects of the processing method.

Now, this same code, when run in Chrome, gives us the following console output:

["Misty May-Treanor", "Kerri Walsh", undefined × 2]
["Misty May-Treanor", "Kerri Walsh"]

Having little experience with Chrome Dev Tools, I saw the above output and immediately thought:

"Our first log() looks really weird! Something must be wrong with the way data is being assembled in the first place!"

Little did I know that the strange, "undefined x 2", notation meant that there used to be data there. It seems that after the initial log, Chrome Dev Tools actually went back and updated the output once the data array had been mutated.

Now, I am sure some of you are looking at this and thinking, "You should be using Breakpoints to debug your JavaScript code anyway." And, Breakpoints are definitely cool. But, that's fixing the wrong problem, in my opinion. As far as I'm concerned, the whole point of a "log" is that the data output to it is fixed. Otherwise, I think the log loses its value.

I, for one, am going to continue using Firebug, where the output feels more expected. But, I wanted to put this out there in case anyone else was unaware of this Chrome Dev Tools behavior.




Reader Comments

@Joel,

Yeah, I guess so - I wonder if can be turned off. I've been trying to Google it and I can't find anything.

As another check, I tried doing this in Firebug:

  • var title = document.getElementById( "title" );
  •  
  • console.log( title );
  •  
  • title.setAttribute( "data-foo", "bar" );
  •  
  • console.log( title );

Here, we are logging a reference to a DOM node. Both logged elements point to the same DOM node. However, Firebug still logs them as different log items (data-foo="bar") is only present in the second log value.

Firebug for the win!

Reply to this Comment

I use chrome debugging tools all the time, so I guess I'm used to it. When I first discovered this, I thought it was weird and tripped over it. But I think of it now as a dump of a pointer. You always get the current value. In fact, you can watch it change in real time. So now, when I need a dump of *this point in time* I use JSON.stringify( varToDump ).

Reply to this Comment

@Rob,

Oh nice, I didn't even think of using the JSON api! We ended up using:

data.join( "," )

... to output it as a static string. But the JSON approach is way cooler (and more flexible). Thanks!

Reply to this Comment

I never even noticed this before thanks for the heads up. I usually just logged specific properties of an object.

I'm seeing this reported at stackoverflow also.
http://stackoverflow.com/questions/7389069/console-log-object-at-current-state
console.log(JSON.parse(JSON.stringify(testObj)));
and
http://stackoverflow.com/questions/11118758/bug-in-console-log

One of the suggestions they have is similar to Robs except they are adding a JSON.parse also.

console.log(JSON.parse(JSON.stringify(testObj)));

This ends up with a nice looking object like I'm used to seeing in Chrome.

Reply to this Comment

In Firebug you have one feature that is similar and that I don't like either.

Say you log an object. Then in Firebug's console you can click on the object to inspect it.

If the object changed before you click on it, then you get the updated version. Too bad :)

That's easy to test in the console :

var a = { test: "test" };
console.log(a);

a.test2 = "test2";

And then click on what got logged before => you see the test2 key.

Reply to this Comment

The problem is Chrome's console is asynchronous.

Instead of waiting for the array to be written to the console, the script goes on to the next line ( calling processSomeData() ). By the time the array is actually output in the console its contents have changed.

The reason things like JSON.stringify() work as that you're creating a new object -- a string -- and passing that to the console instead of the array.

Reply to this Comment

Yeah this bug is a killer. It's the top of our list with stars.. and.. good news in fact!

Today the engineering team landed a patch to help resolve this issue AND give us more attractive console logging at the same time!
http://trac.webkit.org/changeset/125174

So now we'll get a preview of the object at the time of logging and we'll likely be avoiding this pesky one going forward.

:D

Try out the Canary tomorrow!

Reply to this Comment

["Misty May-Treanor", "Kerri Walsh"]
["Misty May-Treanor", "Kerri Walsh"]

My Chrome with newest update show this, how to fix it to show the right?

Reply to this Comment

@Son,

Maybe it's still in the nightly build, not in the main Chrome release? I don't know much about the bleeding edge stuff; I just have the standard Chrome builds.

Reply to this Comment

It's stable build, my browser was auto updated.
BTW, thank you, I'll look around to fix it.

Reply to this Comment

I use chrome debugging tools and I have great experience with it.. thanks for sharing it to know every developers to better understand.

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.