This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

Some tricks for debugging JavaScript

Whilst a modern browser developer console usually provides an excellent debugger, sometimes debugger breakpoints are simply not the easiest way to track down bugs.

An alternative is to log data to the developer console. Littering code with calls to console.log() can provide the right clues, but becomes a nuisance when you are forever editing code to add or remove logging calls, and you then need to remove them all when the script is goes live. It can also be a hassle where browsers do not support the console.log().

console.log() is a nice intelligent method that can take a list of arguments and in most browser developer consoles will show objects in a drill-down widget so you can dig inside them.

A simple way to control the use of console.log() is to make the call to console.log() conditional on a debug flag.

<script type="text/javascript">
$(document).ready(function(){

     var debug_flag=true;

    // Use this wherever you like througout your script
    debug_flag && console && console.log(list_of,msg_or_object);

});
</script>

Here, the code only executes if the debug_flag is set. Then it only executes if the console exists.

You could be hyper-paranoid and use an extra guarding test for 'log' existing on the console object, but I have yet to find that necessary. Maybe its because I only enable the debug_flag when using a decent browser!

<script type="text/javascript">
$(document).ready(function(){

    var debug_flag=true;

    // Use this wherever you like througout your script
    debug_flag && console && console.log && console.log(list_of,msg_or_object);

});
</script>

During development, you can just change or comment out the declaration of debug_flag and all the calls to console.log() are deactivated.

With a larger development, maybe you want to switch the logging on and off from the site’s config/site.php or from a setting elsewhere in the php side of your code.

<?php
define('PACKAGENAME_DEBUG',true);
?>

and

<?php
if (defined('PACKAGENAME_DEBUG') && PACKAGENAME_DEBUG){
    $package_debug_flag = true;
}
?>
<script type="text/javascript">
$(document).ready(function(){

    var debug_flag='<?php echo $package_debug_flag;?>';

    // Use this wherever you like througout your script
    debug_flag && console && console.log(list_of,msg_or_object);

});
</script>

Here, the JavaScript variable debug_flag is either '1' or '', which evaluate as true or false respectively.

Once a development is working and ready to go live, all the deubug code would usually be removed before a final set of tests. But perhaps you want to preserve the capability for future developers.

In situations where I want to keep the console.log() capability in live code, I like to be a little more defensive with the define to guard against another developer mistakenly using 'false' instead of false to disable the console.log() output.

<?php
if (defined('PACKAGENAME_DEBUG') && PACKAGENAME_DEBUG && PACKAGENAME_DEBUG !== 'false'){
    $package_debug_flag = true;
}
?>
<script type="text/javascript">
$(document).ready(function(){

    var debug_flag='<?php echo $package_debug_flag;?>';

    // Use this wherever you like througout your script
    debug_flag && console && console.log(list_of,msg_or_object);

});
</script>

Sometimes I like to make it a little tidier by putting it in a function:

<?php
if (defined('PACKAGENAME_DEBUG') && PACKAGENAME_DEBUG && PACKAGENAME_DEBUG !== 'false'){
    $package_debug_flag = true;
}
?>
<script type="text/javascript">
$(document).ready(function(){

    var debug_flag='<?php echo $package_debug_flag;?>';

    var debug = function (){
        debug_flag && console && console.log(arguments);
    };

   // Use this wherever you like througout your script
   debug (list_of,msg_or_object);

});
</script>

Finally, when leaving diagnostics in live code, the conditions to test for console.log() are not as efficient as they could be.

If used within an inner scope, the JavaScript interpreter has to search up through the various scopes until it finds the console object as a property of the window object. This can be shortened by telling it to look for it straight in the window object.

If performance is an issue, maybe its not such a good idea to declare a debug() function because of the function call overhead and the need to resolve the scope of the function name.

<?php
if (defined('PACKAGENAME_DEBUG') && PACKAGENAME_DEBUG && PACKAGENAME_DEBUG !== 'false'){
    $package_debug_flag = true;
}
?>
<script type="text/javascript">
$(document).ready(function(){

    var debug_flag='<?php echo $package_debug_flag;?>';

    // Use this wherever you like througout your script
    debug_flag && window.console && window.console.log(list_of,msg_or_object);

});
</script>

Which variation of this trick you use is completely dependent on what you are developing, what the JavaScript performance requirements are, how complex the code is and a lot of personal preference.

Have a look at jQuickie - a JavaScript development environment in a block.

Read more How-tos by JohntheFish

Loading Conversation