31 Oct 2011

Dereferencing deeply nested properties in JavaScript

As far as syntax sugar goes, my favorite would be Groovy’s ? operator which allows safe dereferencing of properties, and thus helping to avoid NullPointerExceptions. A quick example: Say, we have a person object who might have a subscription. If he has a subscription, let’s say that the subscription has a startDate.

Now, if we want to print just a particular user’s subscription start date on the screen, we would need to explicitly check if the user has a valid subscription first (it might null) before trying to access it’s startDate property. By using the the ? operator, we can simply write:

// in groovy, I can simply do:
def startDate = person?.subscription?.startDate  
println startDate // startDate will be null if `subscription` is null

This can really make your code look pretty when you are dealing with objects with deeply nested properties, and you are trying to generate a report which accesses fields 5 or 6 levels down (nightmare!).

JavaScript, of course, has no such syntax sugar, but I stumbled on a neat way to dereference such deeply nested properties. Same example in JavaScript.

var person = {
    'id': 112,
    'subscription': {
        'startDate': '2010-11-03'
// throws an error if `subscription` is null !
var subscriptionStartDate = person.subscription.startDate;
// instead, we can write it like this:
var startDate = person && person.subscription && person.subscription.startDate;

Now, startDate will be set to null if subscription is null. Awesome, isn’t it? That looks much better than using multiple levels of ifs.

Bonus tip

What if we wanted to set a default value of “NIL” to startDate in case it’s null (say for screen formatting purpose)? We can do that too:

var startDate = person && person.subscription 
                       && person.subscription.startDate || "NIL"

This works pretty much the same way as the technique used in setting default arguments in JavaScript.

One thing to watch out for

Remember that in JavaScript: false, 0, null, undefined, NaN, and the empty string "" are all falsy values, so using || will override the falsy value with your default value (though, I don’t see this being a problem here, since we are explicitly trying to dereference a property on an object).

Leave a Reply