What is the JavaScript event loop?

I remember the first time I saw a setTimeout( fn, 0 ) call in some React. Luckily there was a comment with the code, so I kind of had an idea of why that code was there. Even with the comment though, it was still confusing. 

Since then, I’ve read several articles about the event loop and got to a point where I was fairly comfortable with my understanding. But, after watching this JSConf talk by Philip Roberts, I feel like I’ve got a much better understanding.

In the talk, Philip uses a slowed down demonstration of the event loop to explain what’s going on to his audience. Philip also demonstrates a tool that he built which allows users to type in code and visualize all of the parts that make JavaScript asynchronous actions work.

You can check out the tool at http://latentflip.com/loupe, but I’d recommend doing it after watching the video.

How to retry Selenium Webdriver tests in Mocha

While working on some functional tests for a hosting provider, I kept running into an issue where the login test was failing due to a 500 error. It appeared as if the site hadn’t been fully provisioned by the time my test was trying to login.

Initially, I attempted adding timeouts to give the installation process more time, but that seemed prone to error as well since the delay was variable. Also, with a timeout, I would’ve had to make the timeout be the longest expected time, and waiting a minute or so in a test suite didn’t seem like a good idea.

Getting it done

You think it’d be a quick fix, right? If this errors, do it again.

Within minutes, I had found a setting in Mocha that allowed retrying a test. So, I happily plugged that in, ran the test suite again, and it failed…

The issue? The JS bindings for Selenium Webdriver work off of promises, so they don’t quite mesh with the built-in test retry logic. And not having dug in to promises much yet, it definitely took me a bit to wrap my head around a solution.

That being said, there are plenty of articles out there that talk about retries with JavaScript promises, which helped bring me up to speed. But, I didn’t find any that were for specifically retrying promises with Selenium Webdriver in a Mocha test suite.

So, I learned from a couple of examples, and came up with a solution that’d work in my Selenium Webdriver Mocha tests.

The Code

You can find a repo with the code and dependencies here, but for convenience, I’m also copying the relevant snippets below:

The retry logic

This function below recursively calls itself, fetching a promise with the test assertions, and decrementing the number of tries each time.

Each time the function is called, a new promise is created. In that promise, we use catch so that we can hook into the errors and decide whether to retry the test or throw the error.

Note: The syntax looks a bit cleaner in ES6 syntax, but I didn’t want to set that up.

var handleRetries = function ( browser, fetchPromise, numRetries ) {
    numRetries = 'undefined' === typeof numRetries
        ? 1
        : numRetries;
    return fetchPromise().catch( function( err ) {
        if ( numRetries > 0 ) {
            return handleRetries( browser, fetchPromise, numRetries - 1 );
        }
        throw err;
    } );
};
The test

The original test, without retries, looked something like this:

test.describe( 'Can fetch URL', function() {
    test.it( 'page contains something', function() {
        var selector = webdriver.By.name( 'ebinnion' ),
            i = 1;
        browser.get( 'https://google.com' );
        return browser.findElement( selector );
    } );
} );

After integrating with the retry logic, it now looks like this:

test.describe( 'Can fetch URL', function() {
    test.it( 'page contains something', function() {
        var selector = webdriver.By.name( 'ebinnion' ),
            i = 1;
        return handleRetries( browser, function() {
            console.log( 'Trying: ' + i++ );
            browser.get( 'https://google.com' );
            return browser.findElement( selector );
        }, 3 );
    } );
} );

Note that the only thing we did different in the test was put the Selenium Webdriver calls (which return a promise) inside a callback that gets called from handleRetries. Putting the calls inside this callback allows us to get a new promise each time we retry.

Comments?

Feel free to leave a comment if you have input or questions. Admittedly, I may not be too much help if it’s a very technical testing question, but I can try.

I’m also glad to accept critical feedback if there’s a better approach. Particular an approach that doesn’t require an external module, although I’m glad to hear of those as well.

Fix SyntaxHighlighter after Jetpack Infinite Scroll

If you write code on your blog, chances are that you use a syntax highlighter to make the code a bit easier to read. And if you’re on this page, then you likely use the SyntaxHighlighter Evolved plugin.

While this SyntaxHighlighter Evolved works amazing for syntax highlighting, I have noticed that when using this plugin with Jetpack’s infinite scroll, my code snippets weren’t getting highlighted after new posts were added. So, after living with it for the past year or so, I decided to fix the issue.

After doing a bit of searching, I found the following article on Jetpack.com: https://jetpack.com/support/infinite-scroll/#js-events

In that article, they mention how a `post-load JavaScript event is called after posts are fetched and rendered. So, if we combine that with the a call to highlight any code snippets we get this:

/**
 * jQuery is likely already enqueued, but let's enqueue here
 * to make sure things don't explode.
 */
add_action( 'wp_enqueue_scripts', 'moh_enqueue_jquery' );
function moh_enqueue_jquery() {
 wp_enqueue_script( 'jquery' );
}

/**
 * This is where the magic happens.
 */
add_action( 'wp_footer', 'moh_trigger_rehighlight', 101 );
function moh_trigger_rehighlight() {
  ?>
  <script>
    ( function( $ ) {
      $( document.body ).on( 'post-load', function () {
        if ( 'undefined' !== typeof SyntaxHighlighter ) {
          SyntaxHighlighter.highlight();
        }
      } );
    } )( jQuery );
  </script>
  <?php
}

If you take this example and throw it in a plugin or the functions.php file for your theme, then all SyntaxHighlighter code snippets should be highlighted every time infinite scroll retrieves a new page. :party:

Blank Web Page with PhantomJS and CasperJS

Today, I was attempting to debug an issue where some of our functional tests were not running with the new React powered parts of WordPress.com.

As part of the debugging process, I decided to see if the tests would pass when run from my local machine instead of our test server. But, any time I ran a test, the test would fail.

madComputer

An Example Test

Here is part of the test that we use to test the log-in/log-out functionality on WordPress.com

casper.test.begin( 'Can log in to WordPress', function suite( test ) {
    casper.start( 'https://wordpress.com/', function() {
        test.assertExists( '.click-wpcom-login', 'Login link exists on front page when logged out' );
    } );

    casper.run ( function() {
        test.done();
    } );
} );

But, when I run this test, this is the output that I get:

# Can log in to WordPress
FAIL Login link exists on front page when logged out
#    type: assertExists
#    file: logging-in-out.js:3
#    code: test.assertExists( '.click-wpcom-login', 'Login link exists on front page when logged out' );
#    subject: false
#    selector: ".click-wpcom-login"

To debug this test, I dumped the HTML to my terminal and got this: <html><head></head><body></body></html>

The Fix?

After searching a bit, I found this answer.

It seems that there was a mismatch between the version of TLS that WordPress.com uses and the version that PhantomJS uses.

I was able to get my test to work by changing the command to: casperjs test --ssl-protocol=any logging-in-out.js

Perceived Speed and Optimization

I was lucky enough to speak at WordCamp Orlando last December.

My presentation, titled Perceived Speed and Optimization, discussed some examples of improving user experience through optimistic interfaces.

Looking back, I probably should’ve waited a few more months so that I could have come up with more examples and I could’ve talked more in-depth about the subject.

You’ll notice that my talk ends at about 12:30 and the video is over 27 minutes long. My presentation ended up being much quicker than I expected. I was so nervous during this presentation due to the size of the theater as well as the caliber of the audience.

I consider this presentation a learning experience and a push to prepare better next time.

For a better explanation of optimistic interfaces see The Need for Speed: Optimistic Web Interfaces.

JavaScript Masterclass | JSConfUS 2013

This past Friday night, a coworker on Mercury, Enej Bajgoric, shared this video of Angelina Fabbro speaking at JSConfUS 2013.

Based on the title of the video, I was certain that I would come away with a more advanced understanding of closures or some other JavaScript topic.

But, I was pleasantly surprised that the video was non-technical. Instead, Angelina talked about topics such as:

  • What makes a good programmer?
  • What level programmer am I?
  • Are there natural programmers?
  • How to get from intermediate programmer to expert programmer.

The video is just over 22 minutes and, in my opinion, well worth the time it takes to watch.

Working with React joinClasses

Note: joinClasses is now deprecated and you should use classnames. There is an explanation of how to use classnames at the end of the article.

React has slowly been coming together for me over the past few weeks as I have slowly moved from “how do I get this thing to work?” to “how can I factor this out?” mindset.

As I’ve slowly ventured into composition with React, one of the pain points that I’ve had was elegantly concatenating classes.

After a tip from Beau and some searching, my first try at concatenating classes in React was done using the classSet utility. And while I was able to use classSet to concatenate classes in a React component, I didn’t find it to be a very elegant or easily readable solution.

A bit more searching led me to a utility named joinClasses.

Using React joinClasses to Concatenate Class Names

Here is an example of how I am using joinClasses to concatenate CSS classes in a React component.

var React = require( 'react' ),
    joinClasses = require( 'react/lib/joinClasses' );

module.exports = React.createClass( {

    render: function() {
        var selected = ( this.props.selected === this.props.className ? 'selected' : '' );

        return (
            <li className={ joinClasses( this.props.className, selected ) } >
                <a href={ this.props.href }> { this.props.label }</a>
            </li>
        );
    }
} );

this.props.selected above is a string that represents which sidebar link should be selected and this.props.className is the class of the current sidebar link.

If the two match, then we want to add a class of selected to the sidebar item along with any classes that were passed in this.props.className.

If there were more classes to be conditionally added based on props that were passed in, I would look into combining the classSet utility along with the joinClasses utility.

Using classnames instead of joinClasses

React has deprecated joinClasses and has suggested that developers use the classnames node module instead.

So, first things first, you’ll want to install classnames. You can usually do this in the root of your project, and you’ll use this command: npm install classnames. Note, you might want to use npm install --save-dev classnames in order to update your package.json file.

Once you have installed classnames, you will then need to require it in your JSX file.

var classNames = require( 'classnames' );

Once we have required classnames, we should be able to simply swap out joinClasses with classNames. Here’s an updated example:

var React = require( 'react' ),
    classNames = require( 'classnames' );

module.exports = React.createClass( {

    render: function() {
        var selected = ( this.props.selected === this.props.className ? 'selected' : '' );

        return (
            <li className={ classNames( this.props.className, selected ) } >
                <a href={ this.props.href }> { this.props.label }</a>
            </li>
        );
    }
} );

Also, because classnames is so robust and will allow us to send an object to it, we can simplify the code a bit:

var React = require( 'react' ),
    classNames = require( 'classnames' );

module.exports = React.createClass( {

    render: function() {
        var classes = classNames( this.props.classNames, {
            'selected': this.props.selected === this.props.className
        } );

        return (
            <li className={ classNames( this.props.className, selected ) } >
                <a href={ this.props.href }> { this.props.label }</a>
            </li>
        );
    }
} );

Dynamically Add Classes with React classSet

Note: React.addons.classSet is now deprecated and you should use classnames. There is an explanation of how to use classnames at the end of the article.

Earlier today, I needed to add some classes to a link. One class was passed in through a prop, but the other class would be added based on a boolean condition.

It’s simple to access props within a React component, so my first crack at setting the classes looked something like this:

<li className={ this.props.className }>
    <a
        href={ this.props.href }
        onClick={ this.setLayoutFocus }
        className={ this.props.selected === this.props.className ? 'selected ' + this.props.className : this.props.className } >
            <span className="menu-link-text">{ this.props.label }</span>
    </a>
</li>

Eww… check out that nasty looking ternary.

Good thing for pull requests, because that one was denied pretty quickly. In the pull request feedback, Beau Lebens mentioned that there was a CSS utility included with React called classSet.

He mentioned that the React classSet utility would be helpful because I’d be able to build my classes string without having to have a bunch of conditional statements and string concatenation. #winning

So, I went Googling and figured out how to use the React classSet utility. Here’s the relevant documentation for using React’s classSet for class name manipulation.

Here’s an example of how the React classSet utility works from the documentation linked above.

render: function() {
    var cx = React.addons.classSet;
    var classes = cx({
        'message': true,
        'message-important': this.props.isImportant,
        'message-read': this.props.isRead
    });
    // same final string, but much cleaner
    return <div className={classes}>Great, I'll be there.</div>;
}

This is a simple example, but what about the case where the class is passed in via a prop as opposed to just being switched on or off by a boolean?

Second Try with React classSet

This try at adding classes via the React classSet utility allows us to add a class that is passed in via a prop.

render: function() {
    var classes = React.addons.classSet({
        'selected': ( this.props.selected === this.props.className )
    });

    /*
     * Since the className changes from sidebar item to item,
     * we dynamically add this sidebar item's class as a key.
     */
    classes[ this.props.className ] = true;

    return (
        <li className={ classes }>
            <a href={ this.props.href } onClick={ this.setLayoutFocus } >
                 <span className="menu-link-text">{ this.props.label }</span>
            </a>
        </li>
    );
}

Note that in this second try that we are dynamically appending our class that was passed in via the className prop to the classes object.

Then, when we call className={ classes } our string of classes is created.

Using classnames instead of classSet

React has deprecated React.addons.classSet and has suggested that developers use the classnames node module instead.

So, first things first, you’ll want to install classnames. You can usually do this in the root of your project, and you’ll use this command: npm install classnames.

Once you have installed classnames, you will then need to require it in your JSX file.

var classNames = require( 'classnames' );

Once we have required classnames, we should be able to simply swap out React.addons.classSet with classNames. Even better though, since classnames is so robust, we can just pass in this.props.className as an argument.

render: function() {
    var classes = classNames( this.props.className, {
        'selected': ( this.props.selected === this.props.className )
    } );

    return (
        <li className={ classes }>
            <a href={ this.props.href } onClick={ this.setLayoutFocus } >
                 <span className="menu-link-text">{ this.props.label }</span>
            </a>
        </li>
    );
}

Creating JavaScript Keyboard Shortcuts with jQuery

I recently added a keyboard shortcut to a project I was working on.

And while I have used the jQuery Hotkeys plugin for adding keyboard shortcuts recently, I didn’t use a plugin for this project since I only needed a single keyboard shortcut.

Taking a large bit of inspiration from Krasimir Tsonev, who also documented his solution, I came up with this:

(function( $ ) {
var $doc = $( document );
$doc.ready( function(){
$doc.on( 'keydown', function( e ){
if ( ! $( e.target ).is( ':input' ) ) {

// props rauchg for pointing out e.shiftKey
if ( 87 == e.which && e.shiftKey ) {
// `shift` and `w` are pressed. Do something.
}
}
});
});

})( jQuery );

Explanation

First, I create an anonymous function wrapper and invoke it while passing jQuery as a parameter. This allows me to use the $ syntax for jQuery without worrying about collisions with other libraries.

Then, after the DOM has loaded, I attach a keydown event handler to the document. Before I run any logic though, I check to make sure that we are currently not within any input type. This is important as I don’t want to trigger keyboard shortcuts when a user is typing.

After the code ensures that we are not in an input, I check to see if both the shift key and w have been pressed. If so, do some magic!

Update Backbone Model with No Change Events

I recently needed to update an array of models to add a “reflowed” attribute to a comment which would act as a flag to show that the comment had been reordered.

Doing it Wrong

When I was working through this issue, the first thing that came to mind was that I could update the model attributes myself.

This is possible with the following syntax.

model.attributes.attribute = value;

But, this isn’t good software development. So, I trashed that idea.

The Backbone Way

The Backbone way to update a model is:

model.set( { attribute: value } )

But, by default, this will trigger a change event on every changed attribute. For my use case, triggering change events for several models wasn’t necessary.

Looking into the annotated Backbone source code, I noticed that I could pass in an options array that set silent to true. This makes the model update look like this:

model.set( { attribute, value }, { silent: true } );