How to Not Hate Java Script: Tips from the Frontline
How to Not Hate Java Script: Tips from the Frontline
Join the DZone community and get the full member experience.Join For Free
Microservices. Streaming data. Event Sourcing and CQRS. Concurrency, routing, self-healing, persistence, clustering...learn how Akka enables Java developers to do all this out of the box! Brought to you in partnership with Lightbend.
This article was originally published on voxxed under, https://www.voxxed.com/blog/2014/11/how-to-not-hate-java-script-tips-from-the-frontline/
The Debugger Statement
Fundamentally it’s a simple way of adding a breakpoint. If we have code where we loop over an element list and then process the elements...
...we can add the debugger statement inside the loop so that we have a breakpoint on each iteration:
The triggering of the breakpoint happens when the execution of the code is done in the place where we have added it. In cases where there is no debugger handler - for example in most browsers without dev tools - this statement has no effect.
On the dev tools side, it will appear as if we have manually placed the breakpoint.
Use the Console Luke!
Most of the developers use the console.log in for debugging purposes, but did you know about console.warn, console.error, and console.info? :
All of these support C style formatted output like:
console.log("Hello %s", "Brian");
Overview of JS objects using Console.table()
Often we load data from various services and want have a nice view of it on our console - especially when the data is represented as a list of objects. For example, if we were to load a list of beers from openbeerdatabase.com (yes this database exists, and it is awesome). Using the HTTP GET beers, http://openbeerdatabase.com/documentation/beers-get call we receive a list of objects. After receiving the list, we just print it out using console.log:
If we were to replace the console.log with console.table and make the call again we'd get this:
Obviously, the data is shown in a table and it is now sortable using the attributes of the objects. This makes the navigation easier. For example, this is a simple way to visually compare two arrays:
would result in more clear version, especially if we had more sub-arrays:
Getting the Call Trace
Sometimes we want to know the call trace, aka "Who called my function". This is often visible when we get a failure - but even on success, we could get the call trace using console.trace :
Note that console.trace is a non-standard functionality and is not something you should have in production. It is, however, supported by major desktop browsers.
Async Call TraceConsole.trace works just fine for normal function calls. In most developer tools, we get the same call trace when we stop on the breakpoint. When the call is async(callback) this information is not available because the scope of the closure(callback function) is limited to the data that it holds. Fortunately, in the newer version of Chrome dev tools we have the flag async. So what previously would have been a portion of the call information...
...now becomes a full call trace containing the scope of the caller and the callback:
Who’s Changing My Object?: Objects.observe + console.traceSometimes objects get some of their properties changed, but we cannot figure out the cause. In this case, objects.observe comes to the rescue. Let's say we want to check for all changes to our person object:
Since we have combined this with the console.trace, we can also see the call trace. Awesome right?
Well, not so much, since at the time of writing only Chrome supports this and it is a non-standard functionality. Fortunately, it is proposed as part of ECMAscript 7. There is also a similar internal variant for this in Gecko based browser object.watch. Then again, when it comes to debugging, anything we can get is useful. Note that Objects.observe primary function is not debugging, but it is a great side effect.
Who’s Changing My DOM/HTML Element - Aka, Who’s F***ing Up My Code?
In complex applications, we may end up in a situation where we do not know how a certain HTML element got changed, moved, added, or had some of it's attributes modified. One way to figure out is to attach the now deprecated mutation event listeners. The API for this is far from ideal, and there are other shortcomings. The newer browser version comes with an object called MutationObserver, which enables us to watch a certain DOM element.
Suppose we wanted to list all mutations on the entire document, where the document can also be any DOM element selected:
There is also the non-programmable solution we can use in Chrome called DOM breakpointswhich still uses mutation events in the background.
Server Side Logging of Client Side Errors
As simple as that, just add the error handler to the window object and you're done with the client side. The handler can then make an AJAX request to a REST endpoint which will store the error information on your server. You might find out that a client using IE 8 has a lot of issues this way because IE versions predating 9 have no string.trim(). I guess string trim is just not that essential.
Anyway, this what the most basic server side logging of client side errors might look like:
Of course, this is the most basic of solution you can have. There are tons of better solutions out there like http://www.stacktracejs.com/ or http://jsnlog.com/ and a more extensive article on Mozilla hacks. There is also a great Hacker News discussion on this topic, but hey, this is certainly a good start!
Use Google Or Other Analytics Tools to Store Data
I know you are way too busy to be writing any backend code. so why not just store the data in Google Analytics?
You can certainly do this, but note that this is a hack, and there are a lot of better commercial options out there like http://usersnap.com if you want to be really thorough - but even a hack is better than no information, which is what most people have.
Published at DZone with permission of Mite Mitreski , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.