Wasted a couple of “What the hell is wrong here?” moments about this code:

1
2
3
4
5
function doSomething() {}
doSomething()
(function () {
  // self executed
})();

Runtime error: doSomething() is not a function.

Obviously, I missed a semicolon after the doSomething() call, but I didn’t imagine this caused the error.

JS usually forgives about missing semicolons, if next statement is not in the same line. However, having the parenthesis of the self executed function made JS parse code as

1
doSomething()(function (){})();

Which expects the returned value from doSomething to be a function, that is executed with the anonymous function as a first argument.

So in conclusion, never forget semicolons. Ever. Even when just debugging code.

The new ECMAScript 5 brought a lot of enhancements that we used to see only on JavaScript frameworks. The Array class now has methods like forEach, map & filter, which are very useful.

If you need to support older browsers, which you probably do, this filtering method can be also found in MooTools (Array#filter), jQuery ($.grep) and other JS frameworks.

A quick tip to remove all falsy (false, null, undefined, 0, NaN or an empty string) items out of an array:

1
2
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]

Since Boolean constructor is also a function, it returns either true for ‘truthy’ argument or false for ‘falsy’ argument.

For example:

1
2
3
4
5
Boolean(0); // false
Boolean(true); // true
Boolean(1); // true
Boolean(""); // false
Boolean("false"); // true. "false" is a regular, non-empty string

And writing

1
b=a.filter(Boolean);

is actually the same as writing:

1
b=a.filter(function (x) { return Boolean(x); });

What are Asynchronous Functions?

An asynchronous function is a function whose completion depends on the actions of another object. The program in which it runs does not wait for the object to return a result, rather, that object ?pushes? the result when it?s finished. This push comes through the callback function ? a function defined specifically for the purpose of receiving a result, and that object calls the function with arguments it supplies. The signature of the callback function contains these arguments, and uses them in order to complete the procedure.

For example: asynchronous use of XMLHTTP. Upon sending the request to the server, the other scripts keep running while the page continues functioning. The XMLHTTP object has an event named onreadystatechange which is called each time the server returns an answer. This is unlike the synchronous case, where the browser waits for a response from the server. The window ?freezes? and only comes back to life when the response is received. This behavior is simply not Internet-correct, and not user-friendly.

Usually when we have an asynchronous function, we?d like another function to run upon its completion. We?ll put the call to the second function in the callback of the first one.

If we have a large number of functions and callback, they start to depend on each other: when A terminates call B, when B terminates call C, and so on. If I pull B out of the sequence, I?ve broken the chain, because C will not be called.

Case of Asynchronous Functions in Sequence

As an example, we?ll look at this sequence:

  1. Performing a semi-transparency effect on an element to be displayed, and once complete:
  2. A button appears in the element, when clicked:
  3. An XMLHTTP request is sent to the server, and when a response is received:
  4. A message is displayed, alerting that the process has finished.

The division into functions is quite simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function effectElement() {
  var div=document.getElementById("div");
  var opacity=0;
  var iv=setInterval(function () {
      opacity+=.05;
      div.style.opacity=opacity;
      if (opacity>=1) {
          clearTimeout(iv);
          showButton();
      }
  },50);
}
function showButton() {
  var button=document.getElementById("button");
  button.style.display="";
  button.addEventListener("click",function () {
      requestServer();
  },false);
}
function requestServer() {
  var xh=new XMLHttpRequest();
  xh.open("GET","url.htm",true); // true - async call
  xh.onreadystatechange=function () {
      if (xh.readyState==4) {
          div.innerHTML=xh.responseText;
          finish();
      }
  };
  xh.send(null);
}
function finish() {
  alert("finish");
}
window.addEventListener("load",function () {
  effectElement();
},false);

We see here that we can call the next function within each function?s callback. But what would happen if we were to remove one of the functions from the sequence? We?d have to change the function containing the call to the removed function, to call another function. And what would happen if we wanted to change the order? A mess.

Generic Solution for a Sequence of Asynchronous Functions

I?ve tried to think of a generic solution to the problem, a solution which would let me decide which function comes after which with minimum code and maximum flexibility, and where each function calls the next without being dependent on it.

This is the basic syntax:

1
2
3
4
5
6
7
8
var sequence=new Devign.Sequence();

sequence.add(effectElement);
sequence.add(showButton);
sequence.add(requestServer);
sequence.add(finish);

sequence.start();

Within each callback, the current sequence should be advanced by:

1
currSequence.next();

where currSequence is passed with the function as a single argument.

Simple, isn?t it?

We can play with the order of the functions, add and remove as much as we want.

Devign.Sequence Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Devign.Sequence class
if (typeof(Devign)=="undefined") var Devign={};

Devign.Sequence=function () {
  // private fields
  this.list=[]; // a list of functions
  this.index=-1;
  this.aborted=false;

  // public fields
  this.finished=false;
};

// public methods
Devign.Sequence.prototype={
  // adds a new function
  add:function (sequenceFunction) {
      this.list.push(sequenceFunction);
  },
  // starts the sequence from the first function
  // fires 'onStart' if exists
  start:function () {
      this.index=-1;
      this.aborted=false;
      this.next();
      if (typeof(this.onStart)=="function") this.onStart();
  },
  // ends the sequence
  // fires 'onEnd' if exists
  end:function () {
      if (typeof(this.onEnd)=="function") this.onEnd();
      this.finished=true;
  },
  // proceeds the sequence
  // if the sequence has finished calls 'end'
  next:function () {
      // if sequence was aborted - ignore next statements
      if (this.aborted) return;

      this.index++;

      if (this.index==this.list.length) return this.end();

      var currFunction=this.list[this.index];

      // calls the function with the sequence as an argument
      if (currFunction) currFunction(this);
  },
  // aborts the sequence by setting the index to 'not started' and the flag aborted to true
  abort:function () {
      this.index=-1;
      this.aborted=true;
  }
};

Each instance of the class has an array of functions, to which we can add more functions with the method add. Furthermore, there is numerical field named index which tracks the index of the function currently being executed (with -1 meaning the sequence has not yet begun). For each instance we can also define two events: onStart and onEnd. If defined, they will run at the appropriate time. Each time we move forward in the sequence, the index is incremented and the next function is called from the array. The function is called with the parameter this which refers to the instance of the class. The reference to the class is sent so that it may be identified from within the function, and advanced with next.

Complete Code

“`javascript
“`

[iframe: style=“width: 100%; height: 600px” src=“http://jsfiddle.net/wXQ4N/embedded/”]

The toElement Method

Classes like Calendar, Slider, AutoCompleter etc. are all containing elements or responsible for elements.

There are several approaches for how to handle the element in the class:

  • Pass a container element as an argument to the constructor of the class, and append to it new elements that the class creates
  • Have the actual behavior-less element(s) on the HTML and pass them to the class constructor as an argument, the class will apply its behaviors on them
  • Create all elements in the class and have them available for appending

Each approach is good for a different situation, but the toElement method is meant mostly for the last one.

Example of a plain class, and how its element is being appended to the document:

1
2
3
4
5
6
7
8
9
10
var AutoCompleter=new Class({
  initialize:function () {
      this.input=new Element("input");
      // autocomplete magic
  }
});

var autoCompleter=new AutoCompleter();

$("container").grab(autoCompleter.input);

This is quite ugly to use the public property input, which its name can be changed someday and then the code breaks. Moreover, in this way, each class declares its own property and this can lead to inconsistency between the property names.

This is where the toElement method comes in handy: it’s a MooTools convention for a method that simply returns the element.

1
2
3
4
5
6
7
8
9
10
11
12
13
var AutoCompleter=new Class({
  initialize:function () {
      this.input=new Element("input");
      // autocomplete magic
  },
  toElement:function () {
      return this.input;
  }
});

var autoCompleter=new AutoCompleter();

$("container").grab(autoCompleter.toElement());

But wait, there’s more: MooTools $ / document.id function knows that if it gets an object that has the toElement method, the method should be invoked and the returned element will be returned out of the document.id function. Luckily, all of the MooTools Element methods use document.id inside them, so, for instance, when grab or adopt are called with any object as an argument, it will be passed thru the document.id function which will translate it to the toElement result. Hence, we can use this:

1
$("container").grab(autoCompleter);

The ToElement Mixin

The ToElement Mixin is supposed to make the toElement method even simpler, and make it lazy-load the element, i.e. create it only when needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var ToElement=new Class({
  ui:{},
  toElement$ensureElement:function () {
      var element=this.toElement$getElement();
      if (!element && this.build) this.build();
  },
  toElement$getElement:function () {
      return (this.ui ? this.ui.element : this.element) || this.element;
  },
  toElement:function () {
      this.toElement$ensureElement();
      return this.toElement$getElement();
  }
});

Usage:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var AutoCompleter=new Class({
  Implements:[ToElement],
  initialize:function () {
  },
  build:function () {
      this.ui.element=new Element("input");
      // autocomplete magic
  }
});

var autoCompleter=new AutoCompleter();
// element isn't ready yet

// the grab calls document.id which calls toElement, where the element is prepared
$("container").grab(autoCompleter);

First, it adds a ui hash to every class instance. That’s my convention to save elements in classes of this kind. Second, it adds a toElement method, which is responsible of calling the build method if exists, and return this.ui.element or this.element out of the instance.

Benefits are:

  • Lazy load the element - it’ll be created only when the document asks for it
  • ui hash to contain all other elements, and a build method as a simple convention

Here’s a neat & clean way to perform a recursion in ASP.NET, inside the .aspx/.ascx file. Suitable for ASP.NET MVC as well as WebForms.

No <asp:Repeater> + OnItemDataBound event, TreeView or concatenating strings recursively in the code behind involved.

Data Structure and Recursive Data Sample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class NodeList : List<Node> {
}

public class Node {
  public string Name { get; set; }
  public NodeList Children { get; set; }
}

public class Repository {
  public static NodeList GetNodes() {
      return new NodeList {
          new Node { Name = "1",
              Children = new NodeList {
                  new Node { Name = "1.1" },
                  new Node { Name = "1.2",
                      Children = new NodeList {
                          new Node { Name = "1.2.1" }
                      }
                  },
                  new Node { Name = "1.3" },
                  new Node { Name = "1.4" },
              }
          },
          new Node { Name = "2",
              Children = new NodeList {
                  new Node { Name = "2.1" }
              }
          },
          new Node { Name = "3" }
      };
  }
}

The Recursive Function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<%
Action<NodeList, int> printNodesRecursively = null;
printNodesRecursively = (NodeList nodeList, int depth) => {
  if (nodeList==null || nodeList.Count==0) return;
%>
  <ul class="node-list depth-<%=depth%>">
<%
  foreach (Node node in nodeList) {
  %>
  <li>
      <%=node.Name%>
      <%printNodesRecursively(node.Children, depth + 1);%>
  </li>
  <%
  }
%>
    </ul>
<%
};
NodeList nodes = Repository.GetNodes(); // Or ViewData use for ASP.NET MVC
printNodesRecursively(nodes, 0);
%>

Notice: The printNodesRecursively function is declared with the value of null at first. Otherwise, the compiler says that the inner printNodesRecursively call is made on an unassigned variable.

This will basically print a

    with an
  • for each node, and inside each
  • , another
      with its children, recursively.

      Notice the extra “depth” which indicates the current depth level in the tree inside the printNodesRecursively function. In this example it adds a special class to each level.

      The Output

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      <ul class="node-list depth-0">
        <li>1
            <ul class="node-list depth-1">
                <li>1.1</li>
                <li>1.2
                    <ul class="node-list depth-2">
                        <li>1.2.1</li>
                    </ul>
                </li>
                <li>1.3</li>
                <li>1.4</li>
            </ul>
        </li>
        <li>2
            <ul class="node-list depth-1">
                <li>2.1</li>
            </ul>
        </li>
        <li>3</li>
      </ul>
      

      (Code re-indented manually :) )

  • The Official Guide to HTML5 Boilerplate
  • Stylebot - a Chrome extension that lets you customize any site’s CSS, like Firefox’s Stylish, or a Greasemonkey for CSS. Great WYSIWYG UI.
  • Firefox 4.0 beta 5 - I’ve been using FF 4 since beta 2, and I’m very pleased. In order to have all add-ons skip the version check, go to the url about:config, create a new boolean key named extensions.checkCompatibility.4.0b with the value of false. Restart FF and most of the add-ons will work.
  • CSS3 Playground - Yet another CSS3 WYSIWYG
  • SmartGit - A UI client for Git. Available for Mac/Windows/Linux

Today I found out something interesting about getElementsByTagName. This method is quite popular, it returns all elements of a requested tag under a specific parent element.

The type which is returned out of a getElementsByTagName call is NodeList, which is not exactly an Array, but is enumerable and has the length property.

When you call document.getElementsByTagName(“div”) you get a NodeList of all div tags, but it seems that every time you use this variable, it shows an up to date list.

Meaning - if you have a NodeList instance of all divs on the document and then you dynamically add more divs to the document, this instance will contain all the new divs as well. Same for removed divs.

Test Case:

“`html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

```js

var divs=document.getElementsByTagName("div");

console.log("divs.length="+divs.length); // 4

document.body.appendChild(document.createElement("div"));
document.body.appendChild(document.createElement("div"));
document.body.appendChild(document.createElement("div"));

console.log("divs.length="+divs.length); // 7

document.body.removeChild(divs[0]);

console.log("divs.length="+divs.length); // 6

[iframe: style=“width: 100%; height: 310px” src=“http://jsfiddle.net/xUsVn/embedded/js,html,result”]

How to Maintain the Original Collection?

Simply, by creating a new Array out of the NodeList’s contents:

1
2
3
4
5
6
var divs=document.getElementsByTagName("div");
divs=Array.prototype.slice.call(divs);
// the above is a shortcut to:
// var tmp=[];
// for (var i=0,l=divs.length;i<l;i++) tmp.push(divs[i]);
// divs=tmp;

MooTools, jQuery, Prototype etc. do not return a NodeList out of their DOM selector engines. They return an Array instance, so no need to worry about this.

This also applies to getElementsByClassName and getElementsByName, but not to querySelectorAll.

I investigated a bit inside the WebKit’s source and it seems like that the getElementsByTagName / getElementsByClassName / getElementsByName methods return a DynamicNodeList while the querySelectorAll method returns StaticNodeList.