About callbacks

March 25th, 2012

Let’s talk about callbacks, people seem to get terrified by them, because they see something like this:

var mysql = require('mysql'),
    db = mysql.createClient({
        user: 'root',
        password: 'root'
    }),
    id = 1;
 
db.query('USE mydb', function (err) {
    //some code here
    db.query('SELECT * FROM whatever WHERE id=?', [id], function (err, foo) {
        if (foo) {
            //some other code
            db.query('UPDATE whatever SET bar=?', [foo.bar], function (err) {
                db.query('INSERT INTO someothertable (sometime) VALUES (NOW())', function () {
                    //some code
                    console.log("It's done");
                });
            });
        }
    });
    //more code
});

This has the potential to turn into hard to understand spaghetti code. But we don’t have to write it like this, we don’t have to inline every function we can simply name them instead.

var mysql = require('mysql'),
    db = mysql.createClient({
        user: 'root',
        password: 'root'
    }),
    id = 1;
 
function init(fn) {
    db.query('USE mydb', fn);
}
 
function fetch(id, fn) {
    db.query('SELECT * FROM whatever WHERE id=?', [id], fn);
}
 
function checker(err, foo) {
    if (foo) {
        //some other code
        update(foo.bar);
    }
}
 
function update(bar) {
    db.query('UPDATE whatever SET bar=?', [bar], function (err) {
        db.query('INSERT INTO someothertable (sometime) VALUES (NOW())', function () {
            //some code
            console.log("It's done");
        });
    });
}
 
init(function () {
    fetch(id, checker);
})

We could also put this in a module or wrap a (pseudo) class around it if we wanted to. The main point is that we don’t have to nest inline callbacks to get the job done, we can name them.

It’s all about the style

March 22nd, 2012

This is how many people like to write code:

<?php
/*
 * Enterprise class backtrack 
 */
 
class Backtrack {
 
    private $values;
    private $stack = array();
    private $results = array();
 
    public function __construct($values) {
        $this->values = $values;
    }
 
    public function search() {
        $this->results = array();
        $this->doSearch();
    }
 
    public function getResults() {
        return $this->results;
    }
 
    private function doSearch() {
        if ($this->reject()) {
            return;
        }
 
        if ($this->accept()) {
            $this->results[]= $this->stack;
        }
 
        $ostack = $this->stack;
 
        foreach ($this->values as $value) {
            $this->stack = $ostack;
            $this->stack[]= $value;
            $this->doSearch();
        }
    }
 
    private function accept() {
        return count($this->stack) > 0;
    }
 
    private function reject() {
        return count($this->stack) > count($this->values);
    }
 
}
 
$bt = new Backtrack(array(1, 2, 3));
$bt->search();
var_dump($bt->getResults());

This is how I prefer to write code:

<?php
/*
 * Functional Backtrack
 */
 
function backtrack_accept($values, $stack) {
    return count($stack) > 0;
}
 
function backtrack_reject($values, $stack) {
    return count($stack) > count($values);
}
 
function backtrack($values, $stack = array()) {
    $results = array();
 
    if (backtrack_reject($values, $stack)) {
        return $results;
    }
 
    if (backtrack_accept($values, $stack)) {
        $results[]= $stack;
    }
 
    foreach ($values as $value) {
        $nstack = $stack;
        $nstack[]= $value;
        $results = array_merge($results, backtrack($values, $nstack));
    }
 
    return $results;
}
 
var_dump(backtrack(array(1, 2, 3)));

What do you prefer?

What they don’t teach you in (W3)school: JavaScript variable scoping

January 27th, 2011

W3Fools is an interesting site I came across that highlights the wrong parts of W3Schools. While W3Schools is the most popular online resource for web standards, its content has a lot of serious flaws.

One such problem at W3Schools is variable scoping in JavaScript(w3schools page):

JavaScript has a global scope(global window object to be more precise), that is the place where all global variables go, usage of this must be minimized because in most pages there will probably be scripts from multiple sources, if everyone relies on the global scope, than sooner or later one script will get into conflict with another. The var keyword is not an optional decoration in JavaScript, if we leave out the var, then the global scope is assumed automatically. Here are some examples:

These functions declared global variables, therefore our local variable loses its original value:

something = 'first thing';
 
function foo() {
    something = 'foo';
}
function bar() {
    something = 'bar';
}
 
foo();
bar();
console.log(something); //'bar'

These functions declared local variables, no collisions have occurred here:

var something = 'first thing';
 
function foo() {
    var something = 'foo';
}
function bar() {
    var something = 'bar';
}
 
foo();
bar();
console.log(something); //'first thing'

W3Schools states the following too:

If you redeclare a JavaScript variable, it will not lose its original value.

While it may not cause an error now it is certainly not a good practice and could lead to confusion and maybe runtime errors in future versions of ECMA Script(JavaScript).

There are also other important facts about the var keyword that are not mentioned in W3Schools:

var is function scoped and not block scoped:

function test() {
    if (true) {
         var test = 3;
    }
}

works just like:

function test() {
    var test;
    if (true) {
         test = 3;
    }
}

Either way you will be able to access the variable test after the block. A better example might be:

for (var i=0;i&lt;10;i++) {
}
console.log(i); //10

The best practice to avoid confusion is to begin each function with a single var declaration and declare all variables in that single var declaration. JSLint can help you with that. And learning more about JavaScript is as easy as watching a couple of videos I outlined in one of my previous posts.

Update:
the best comment this article/issue received so far: http://www.reddit.com/r/web_design/comments/fa9hp/what_they_dont_teach_you_in_w3school_javascript/c1ejet7

Update 2: made the w3schools link weaker.

Update 3: added rel=”nofollow” to w3schools links.

Avoiding SQL

January 16th, 2011

I have been writing dynamic database-backed web applications since 2006, still whenever I fire up my IDE, I can’t help notice that the SQL in my code doesn’t feel natural, my IDE can’t parse it, because in essence, it’s a string that gets created on runtime. SQL itself can be pretty counter intuitive, it has poor support for complex data structures, one of it’s main weaknesses is that(to my knowledge) it can’t return nested structures. In terms of clarity, SQL doesn’t scale well, long SQL strings are really hard to understand.

In real life we have complex and nested data and we need to make our code as clear as possible. A common practice(MVC) is to put all the SQL into data access objects and use it’s API instead of raw SQL. I did just that I had most of my SQL in objects, what I found is that I kept repeating code and kept doing the same thing with every new data access object I made, but at least I always knew the purpose of the SQL queries, because they were encapsulated.

One day I kept hearing about NoSQL databases, they looked to offer something better but I ignored them because most hosting providers don’t support them. A while ago however I heard about object relational mappings(ORM), libraries which provide a native API on top of SQL. This sounded just like what I needed, something that could help eliminate the duplication I previously had with my data access objects.

I searched for an ORM written for PHP and I found Flourish ORM, after finding it I realized that this is what I needed all along. I can create a basic ActiveRecord in 3-4 lines of code, the only thing I need to specify is the database it maps to, the ORM layer reads the schema of the database and gives me dynamic methods that I can use instead of SQL.

//this is how we initialize
class User extends fActiveRecord
{
}
fORM::mapClassToTable('User', 'user');
//this is what we get
$user = new User();
$user->setName('Test user');
$user->setPassword('123456');
$user->store();

That’s it, I get similar methods for the rest of the database operations, one of the main benefits is that I no longer have to worry about string concatenation. I can override these methods at any time using standard OOP techniques. Of course this does not mean that I will never write SQL again, but I will write and maintain a lot less that I was used to. Another big advantage is that there is a standard API for data handling, if someone takes over my code, I could simply point to the Flourish documentation.

Web developer’s guide

December 9th, 2010

I decided to do a compilation of web based resources that help learn web developing. I have strictly sticked to resources that are available on the web for free. I tried to categorize them by skill level. This will probably get revised a lot, I am looking forward to suggestions. Nearly none of this is my own work and I may be biased towards certain authors.

Beginer

Google Code Uniersity is a really good place to start learning the basics of web developing, I recommend the following tutorials:

HTML, CSS, and Javascript from the Ground Up

CSS, HTML and Javascript

AJAX Tutorial

Advanced

YUI Theatre is one of the places that has a lot of interesting talks where a developer can learn more about how the web actually works and how a developer could improve things. These are the ones that I think web developers should watch:

A developer needs to fully understand JavaScript as a programing language.

Douglas Crockford – The JavaScript Programming Language part 1part 2part 3 and part 4 – this is a must view for every web developer, it really helps understand how JavaScript actually works and how we can program in it effectively.

The good parts of the language need to be learned.

Douglas Crockford - JavaScript: The Good Parts

A developer should understand that the browser’s DOM API is broken.

Browser Wars Episode II: Attack of the DOMs – Presented by the Silicon Valley WebBuilder, this event brought together Mike Shaver from Mozilla, Chris Wilson from Microsoft’s IE team, Håkon Lie from Opera, and moderator Douglas Crockford from Yahoo! to talk about the current state of the browser landscape. This video helps understand why is the web broken even today.

Douglas Crockford — An Inconvenient API: The Theory of the DOM

Using libraries is mandatory.

John Resig: “Advancing JavaScript with Libraries” part 1 and part 2 – Johen Resig is the author of jQuery. He talks about how JavaScript libraries work, what they do and how can they help a web developer do more and worrying less about how the DOM works.

Christian Heilmann — YQL and YUI: Building Blocks for Quick Applications

Beyond…

Those who want to create really heavy client side web applications need to aspire for quality.

Douglas Crockford: “Quality” – this can teach a programmer new ways to look at code and measure it’s quality.

Being cutting edge is also very important, if we want to have a future, we must be ready for it.

Brad Neuberg — Introduction to HTML5 – there are a lot of things that are already there and we can make use of.
Brendan Eich — ECMA Harmony and the Future of JavaScript

Speed is very important, it could mean the difference between success and failure, so being able to optimize successfully is a big win.

Joseph Smarr: “High-performance JavaScript: Why Everything You’ve Been is wrong
Nicole Sullivan — Design Fast Websites
Nicholas Zakas – Speed Up Your JavaScript

In terms of CSS a web developer needs to avoid bloating it.

Nicole Sullivan – Top 5 Mistakes of Massive CSS

Starting easy
http://ontwik.com/html5-2/paul-irish-on-html5-boilerplate/

JavaScripting is possible on the server side too, and it can be really powerful.
Ryan Dahl — Introduction to NodeJS
Douglas Crockford — Crockford on JavaScript — Scene 6: Loopage
Dav Glass — Using Node.js and YUI 3

Developers coming from other programing languages

JavaScript is a unique language, and can suprise developers coming from other languages.

C# developers should check out:
How Good C# Habits can Encourage Bad JavaScript Habits: Part 1
How Good C# Habits can Encourage Bad JavaScript Habits: Part 2 – False-y, Testing and Default Values, Comparisons, and Looping

Conditional JavaScript

October 20th, 2010

Having conditional comments and CSS references inside them is good, having conditional comments give the body or html element a class is better, but in my opinion having all this in a JavaScrip file is better.

First thing is to take this code:

var IE = (function() {
  var undef, v = 3, div = document.createElement('div'),
      all = div.getElementsByTagName('i');
  while (
      div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
      all[0]
  );
  return v > 4 ? v : undef;
}());

Now we have a reliable variable called IE which contains either undefined or the IE version. Now we can do real fun stuff with this:

/*IE support*/
if (IE==6) {
    $.getScript('lib/DD_belatedPNG_0.0.8a-min.js', function() {
        DD_belatedPNG.fix('img, .textInput, .apng,.picture-box-frame');
    });
}
 
if (IE) {
    $('html').addClass('ie');
    $('html').addClass('ie'+IE);
}

We can load IE specific hacks from the script tag without bloating the HTML header and we can also add CSS classes to top level elements without filling our HTML header with conditional comments. This is a really clean and flexible approach that doesn’t force you to make your header look like trash.

NoScript

NoScript people will simply tell you that: “If the user has JavaScript disabled this will not work”

According to Yahoo approx. 2% of the US visitors have JavaScript disabled and far less in other parts of the world. But let’s take the 2% for users who for some reason don’t have JavaScript enabled, and discard everyone but the IE users and we get a number that’s far less then 2%. This is highly dependent on the product but if I have to break the experience for less then 2% of my users for the benefit of the remaining 98%, I think I will go with it.

A lot of IE hacks(like PNG hacks) will not work without JavaScript anyway so the user will still have a broken rendering even if I put the conditional CSS in the HTML.

Disabled JavaScript myths

October 13th, 2010

A lot of people are debating on whether or not is it worth developing for users that have disabled JavaScript or not. I already talked about this, so instead I am gonna bust a few myths that are supposed to be reasons for disabling it:

1) Using JavaScript is insecure.

JavaScript is a programing language, not a security hole. Calling JavaScript a security hole is the same as calling any other programming language a security vulnerability. In fact JavaScript’s DOM environment is one of the few that makes a difference between user and non-user generated events on a very deep level.

2) JavaScript is a privacy threat.

JavaScript has nothing to do with privacy, cookies should be disabled for better privacy, but then very few login systems would actually work.

3) JavaScript saves bandwidth.

Well actually quite the opposite is true, while you do not download the JavaScript source files, you actually end up downloading a whole page on every interaction instead of partial page replacements with AJAX. Also JS files are cached so a lot of common knowledge on interaction could be cached, thus requiring only the least amount of information from the server.

I assume most users who disable JavaScript simply don’t understand it or have a computer and browser combination from the last millennium, or maybe simply feel to classy or old schoolish for this. I wonder how many of them leave Flash enabled…

What is NOT a browser

October 4th, 2010

In the beginning computers didn’t have sound capabilities, later on they could get that by inserting optional sound cards. Some computers shipped with sound cards already included, but a lot if not most were shipped without. After a lot of years have passed, most motherboard manufacturers started integrating sound cards into the motherboard. The question here is: what did the multimedia industry do while all of this was happening(for years)?

At first there were apps that emitted sounds by using the PC Speaker, then hybrid apps were born, where the app could use either the PC Speaker or the sound card. Does the industry care about people without sound card today? No. I don’t think it’s even possible to get access to the PC Speaker anymore. I have never seen a game where the game would close caption the sounds if it found out that I didn’t have a sound card, maybe if I am deaf but that’s another story.

The story of  sound card and the PC is very similar to the story of JavaScript and the browser, with the exception that a lot of today’s web developers still insist on making web applications that will work even without JavaScript. JavaScript was invented in 1995(15 years ago) and it’s in every browser that has at least 1% market share, but still we have people who think it’s just optional.

My take is that every web application should work the best it can in every situation but it’s unreasonable to accept it work identically in every situation. If I have a news site it’s reasonable to have the article’s content accessible without JavaScript, but it’s unseasonable to have my lightbox-like gallery work without JavaScript.

Applications that we today call browsers must: understand HTML, render CSS and run JavaScript. There is no in-between if an application can only accomplish one or two of the 3 tasks it’s simply not a browser, it’s something else. We have search engines that typically understand HTML(and a subset of CSS to prevent cheating), in some cases we need to make our content accessible to them, these robots only care about our content, they need to know little about what GUI functions does our site provide.

Knowing all this I only care about two things: search engines and browsers. My first step is always creating HTML to be as semantic as possible(HTML does not make this easy), when that’s done I lay CSS on top of it and make sure it works in modern browsers, then I use a special JavaScript inspired by this post to create elegant IE specific CSS rules. My workflow received criticism because I required legacy(IE) browser to have JavaScript for the CSS rules. I found this dubious because I don’t really think that we can call something a browser if it does not run JavaScript, especially if it’s a legacy application. We should develop for the future not for the past.

We should develop for the majority and not for the minority, if 0.1% of our users have a legacy browser and JavaScript disabled, it’s probably not worth multiplying our development time just for the sake of 0.1% of potential users. The other fact is that if we let users use our web applications without JavaScript they will always feel comfortable disabling it. We need to take the web forward which is impossible if we make our users view JavaScript as an extension.

Any entity with finite resources should consider the above before diving into developing, it’s always important to measure the impact and the resources spent.

Behaviors – Extending HTML

September 13th, 2010

HTML is a markup language which most of the time lacks the elements/capabilities that we really need, not even HTML5 could have all the things we need now and in the future. Most UI frameworks get around this by giving a JavaScript API to create new widgets which utilize the DOM API and CSS to associate looks and behaviors to elements. We don’t need to stop here, we can take this further, we can describe new widgets and extend HTML.

How do we accomplish this?

jQuery has a really powerful method called .live() which can:

Attach a handler to the event for all elements which match the current selector, now or in the future.

So basically we can create CSS like rules for elements with JavaScript. Most of the code we write with jQuery are meant for elements that exist, but with live we can make our code work for future elements as well.

Examples speak for themselves

Let’s say we would want to create a send button which behaves like an input[type=submit] element. Let’s name this tag “send”, and let’s write some markup for it:

<send>Send me</send>

Since this is not a standard HTML element we need to assume that it works like a div and style it:

send {
border: 1px solid #000;
padding: 5px;
cursor: pointer;
}

This styling will only work in older IEs if we hack a little in JavaScript:

document.createElement('send');

Now that we have our new element, but we still need to assign it our desired behavior:

$('send').live('click',function(){
    $(this).closest('form').submit();
});

Translation: whenever you click a send element, submit it’s parent form.

With relatively short and easy to read code, we have created our custom HTML element. Now this is not a very useful element, but that doesn’t mean we couldn’t create something very useful with the same technique. My first idea was to implement the HTML5 placeholder(rollover) feature for browsers that don’t support it.

Sadly jQuery live can only capture events on future elements, but it can’t tell us if a new element has appeared in the DOM, so for this we will need the help of the livequery plugin to give us this feature. Since we are implementing a HTML5 feature we need to be careful and make sure that it’s not already implemented in the browser, for this we will need Modernizr.

The code:

(function(window,document,$,undefined) {
    //check for placeholder support
    if (!Modernizr.input.placeholder) {
        //default to placeholder when loose focus
        var blur = function(e) {
             if (!$(this).val().length) {
                  $(this).val($(this).attr('placeholder'));
             }
        }
        //if the value is the placeholder, empty the field
        var focus = function(e) {
             if ($(this).val() == $(this).attr('placeholder')) {
                  $(this).val('');
             }
        }
        //assign the events
        $("input[placeholder]").live('blur',blur);
        $("input[placeholder]").live('focus',focus);
        $("input[placeholder]").livequery(blur);
    }
}(window,document,jQuery));

Download Examples

Again with relatively little pain we managed to make a HTML5 feature work in all browsers. Of course we could have written a jQuery plugin extension for this, but it’s a lot cleaner to simply think HTML5 and let the browser use it’s built in feature if it has any. jQuery live can be used for a lot of other purposes, in my opinion it is definitely worth learning and using along with the livequery plugin.

jQuery AJAX Enhance

July 7th, 2010

It is probably clear as the sky that I have much love for jQuery, it’s a tool that saved me time and money. The good thing about jQuery is that it is simple, and it allows extensions(plugins), which make it virtually invincible.

I was working on a project where I had a lot of jQuery UI Dialogs, with forms and OK and Cancel buttons. I virtually repeated the same code over and over: if the user clicks Ok, submit the form, which is easier said than done. $.ajax is awesome, and I could easily send form data if I combined it with $.serialize, so it wasn’t that bad, but then I thought to myself, what if I’d make a version of $.ajax that was for forms.

So my idea was to have:

$(formselector).ajaxPost(url,func,dataType);
$(formselector).ajaxGet(url,func,dataType);

and make these work just like $.ajax, it would serialize the form data and send it. Naturally if I would leave out the url parameter it would try to detect it from the action attribute of the form.

This was very good, it worked, but still it wasn’t enough, I couldn’t do file uploads with these, because to my best knowledge, jQuery doesn’t support it. I could not accept not having file uploads so I took YUI Connection Manager(which supports file uploads) and wrapped it around my jQuery-ish syntax.

The result is the following:

$(formselector).ajaxUpload(url,func,dataType);

Which almost works like my previous extensions with the addition, that it can upload files. This feature is dependent on YUI Connection Manager(bundled in package), if it’s absent, the usage of this method will throw an exception, however the other two will work as expected, because they are fully coded in jQuery. This of course means that if there is no need for file upload support, the YUI components can simply be left out.

If anybody would be interested in this, it’s available under MIT and GPL, go grab it and hack it:

Download jQuery AJAX Enhance 0.9