Proxying Console.log
Jsbin.com, almost all JavaScript developers will be familiar with this website.
When I first started using this website for small scripts, quick proof-of-concept, what I noticed was that they have their own console pane where all the output of console.log interpreted.
Look at the figure below.
In the above jsbin figure, the console.log default output is in the chrome window, as well as in the “Console” window of jsbin.
Here’s the animated version.
That piqued my interest. How could they interpret console.log and proxy request to their window along with the default log output, i.e. chrome’s debugger window.
That’s exactly where proxy design pattern comes into play though not very obvious because JavaScript natively has support for this kind of features.
The good thing JavaScript being dynamic in nature is kind of a boon to developer as we can tweak the language to our need.
Remember the words of wisdom by Spiderman’s uncle
With great power comes great responsibility.
So, use it with caution and let the action begin.
Proxy Pattern
Definition
Provide a surrogate or placeholder for another object to control access to it.
Luckily in JavaScript due to dynamic nature we can use the language feature to meet this goal. We don’t actually need to create a surrogate, but we can directly take control of console.log method and add new behavior to it.
Caution: The purist out there might not agree with this approach of proxy pattern, but what matters is the concepts behind these design pattern and how we can use the language features to leverage their benefits.
We are building a custom log window, which we can embed in any HTML page.
The final application will look like the figure below.
Do note that I have done only minimal styling to keep the post to the point.
We can enable a custom log window on any page. We are only extending the behavior of console.log. The output is shown in the chrome default debugger as well as our custom window.
Our custom window also has a input field, where JavaScript code can be entered. On press of Ctrl + Enter the code will be executed. Just like chrome does.
Kindly note, we are only targeting the minimum feature. The live app can be viewed here on jsbin.com. Ensure the “Output” panel is open.JS Bin
A live pastebin for HTML, CSS & JavaScript and a range of processors, including SCSS, CoffeeScript, Jade and more…jsbin.com
Let the digging being.
First see, how we will use this. To enable log capturing we will set the SHOW_CUSTOM_CONSOLE to true.
JS Magic. We can add custom property to existing object. In this case we are adding the variable to the console object.
console.SHOW_CUSTOM_CONSOLE = true;
After this statement any console.log, should be redirected to our custom window.
console.log(“Hello world!”, “greetings”, “js”);
console.log(“My own console window..”);
console.log(“Success”);
Let’s see the implementation. I will put the full code here with comment. If you put this code in a file and include it in your projects, then you can enable the custom logger by setting SHOW_CUSTOM_CONSOLE to true on the console object.
The crux of the thing is in line 13–20 where we overide the log method and line 54–61 where the dynamic JS expression evaluation is done.
Also, the basic css for the above code is in the below gist.
.console-container {
position: absolute;
background-color: #16a085;
width: 100%;
min-height: 100px;
bottom: 0;
}
.console-output {
margin: 1em;
width:94%;
min-height: 100px;
max-height: 200px;
background-color: white;
overflow: auto;
}
.console-edit {
margin-top: 1em;
margin-left:1em;
margin-right: 1em;
margin-bottom:0;
height:1.9em;
width: 94%;
}
.console-output-data {
padding: 0.3em;
border: 1px solid #ecf0f1;
}
Better Practice: I could have cached the elements for better performance. But for this small demo I duplicated the code.
Please note: This is for educational purpose only, but you can use this technique for lot of other applications, internal to your apps. Also, note overriding existing objects is not considered good practice, but many unique applications can be build using this technique, as long as you are internalizing the code withing your framework/library.
Let me know in case you need explanation on any part of the code. Feel free to leave your comment.
Updates:
- Added animated gif and some notes.
Happy Digging!!