Why Does YUI Have a Y.one() Method?

When I was working on the YUI 3 Cookbook, one of the things I really enjoyed was being able to pick the brains of the YUI team and get a straight-from-the-horse’s-mouth account of YUI’s architecture and design. With the release of the cookbook, I thought it would be fun to look back through the manuscript and pick out some short topics that might be of interest to new and intermediate YUI users.

One basic thing you might be wondering about is… why does YUI have two idioms for reaching into the DOM?

YUI’s first method, Y.all(), retrieves a Y.NodeList instance:

var errorDivs = Y.all('div.error');

If the selector fails to match any elements, Y.all() returns an empty Y.NodeList.

By contrast, the second method, Y.one(), retrieves a single Y.Node instance:

var errorDiv = Y.one('div.error');

If the selector matches multiple nodes, Y.one() returns the first match (as if you were using the :first jQuery pseudo-selector). If the selector fails to match any elements, Y.one() returns null.

So what’s up with this? Why bother having two methods, and why do they behave so differently? Why not just have querySelectorAll()-like behavior and be done with it?

The answer is that it’s helpful to know ahead of time whether you will receive a single node or a collection. This in turn is why the two methods return different values when the selector fails to find a match. Since Y.one() returns null, it is great for simple node existence checks:

if (Y.one('#myDiv')) {
    ...
}

As for Y.all(), the fact that it always returns an empty collection makes it always safe for doing bulk operations. For instance, the following works just fine even if there are no error divs in the document:

Y.all('div.error').remove();

Some libraries rely on a single abstraction (reaching into the DOM always returns a collection), but the choice of Y.all() and Y.one() — or, if you’re thinking in native terms, querySelectorAll() and querySelector() — ultimately enables you to write cleaner code. The cost is having an extra API method to think about. Fortunately, YUI’s methods have short, distinct names, so it’s pretty easy to remember which one does what.