Skip navigation

Tag Archives: API

We’ve recently added two new API’s on XPCOMUtils that make a common coding pattern simpler to do. It is quite common to have “smart getters” to store a reference to a service that you use in JavaScript. Normally, folks write code that looks something like this:

this.__defineGetter__("_ioService", function() {
  delete this._ioService;
  return this._ioService = Components.classes["@mozilla.org/network/io-service;1"].
                           getService(Components.interfaces.nsIIOService);
});


That gets long and verbose if you have any more than a few of these getters. The new approach looks like this:

XPCOMUtils.defineLazyServiceGetter(this, "_ioService",
                                   "@mozilla.org/network/io-service;1",
                                   "nsIIOService");


The net result is a lot less boilerplate code, which, in my opinion, is a lot nicer to read. I’ve already converted the toolkit code in the Places module over, and the resulting code is much nicer.

Sometimes, however, you want to have a getter for something that is not a service. That’s where the second API comes in. You can pass in a lambda function that will be called when the value is needed for the first time. From then on, the value is cached. Some old code may look something like this:

this.__defineGetter__("_db", function() {
  delete this._db;
  return this._db = Components.classes["@mozilla.org/browser/nav-history-service;1"].
                    getService(Components.interfaces.nsPIPlacesDatabase).
                    DBConnection;
});


With the new API, that code turns into this:

XPCOMUtils.defineLazyGetter(this, "_db", function() {
  return Components.classes["@mozilla.org/browser/nav-history-service;1"].
         getService(Components.interfaces.nsPIPlacesDatabase).
         DBConnection;
});


Again, much nicer looking! If you are interested, the implementation of these methods can be found here.

Did you know about the handy NetUtil object available when you import NetUtil.jsm? I bet you didn’t since it’s fairly new! There’s no MDC page yet, but the API is getting even better. Bug 508902 added a new method on NetUtil to create nsIURI objects. NetUtil will cache the IO Service so the calling site doesn’t have to. As more code starts to use this, fewer objects will have to cache the IO Service themselves.

The API mirrors nsIOService‘s newURI method with one minor improvement; the last two arguments are optional. Most callers in JavaScript tend to pass null for those last two arguments anyway, but when using NetUtil.newURI, they just have to pass the spec which should be easier.

New JavaScript code that needs to create nsIURI objects should start using this method.