Post Truthy World

Don’t worry- this is not about to get political.  Unless you get really fired up that Javascript equates zero to false.  If you’re a real zero-rights advocate, trigger warning.

If I remember correctly, a little while ago I went off on a tangent about ways to pass default parameters to a function in Javascript.  One of the ways mentioned (back before the glory of our new ES6 overlords) was to check for a parameter’s existence at the top of a function, and if it’s not there, assign a default.

Something like:

function defaults(foo, bar) {
    const myFoo = foo || 'Foo default';
    const myBar = bar || 'Bar default';
}

And that generally works pretty well.  But it’s important to remember that this is the wild world of JS we’re talking about.  That logical or operator – the || bit up there- checks the ‘truthiness’ of the param.  That means, if it’s an empty string, or undefined, or the boolean false value, or many other options, it will evaluate to false and grab the second value.  When it doubt, check MDN (Truthy, Falsy).

I’m usually pretty good about making sure this is going to work, but got a bit overconfident on a recent project.  Another throwback to an old post- I was working on a pagination feature for our Angular application.  One method in the service was called setGrid- this is what any other component could call when a page number was clicked, new data came in, or a filter/search was applied to the page, and it would update the page display and other page listings.  It went something like this (remember we are using typescript and this is inside an ES6 class:

setGrid(start: number, length?: number) {
    let sentLen = length || this.prefilteredItems.length;
    this.paginationService.setGrid(start, sentLen);
}

It seemed to work great, so I moved on to other aspects of the project. No one else noticed anything either at first.  But the trouble was with a search/filter that yielded no results.  If there were no items found, nothing displayed in the grid (as it should function), but the page numbering and links below would display the previous search numbers (or the full list numbers, which the ‘prefilteredItems’ array defaults/resets to).

And that was because the number zero is a perfectly valid result.  Sometimes, the length parameter would be zero- as in ‘no results found’- and there should be no pages or numbering.  But when zero was passed to the function above, it just registered as ‘falsy’ and evaluated to the right hand side- giving the full list (or prefiltered list) total as length.

Once I noticed that issue, the fix was easy: Check for undefined specifically.  The final version looks more like this.

setGrid(start: number, length?: number) {
    let sentLen = length;
    if(length === undefined) {
        sentLen = this.prefilteredItems.length;
    }
    this.paginationService.setGrid(start, sentLen);
}

It’s a bit longer and doesn’t look as slick without the || operator, but in some cases the shortcut just won’t work.  Sometimes zero is a valid submission.  As in the sign that should hang above my desk: “It’s been 0 days since our last bug created”.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s