NettutsPlus

  • Wed, 22 Feb 2012 21:05:09 +0000: Wrangle Async Tasks with jQuery Promises - Nettuts+

    Promises are an exciting jQuery feature that make it a breeze to manage async events. They allow you to write clearer, shorter callbacks and keep high-level application logic separate from low-level behaviors.

    Once you understand Promises, you’ll want to use them for everything from AJAX calls to UI flow. That’s a promise!


    Understanding Promises

    Once a Promise is resolved or rejected, it’ll remain in that state forever.

    A Promise is an object that represents a one-time event, typically the outcome of an async task like an AJAX call. At first, a Promise is in a pending state. Eventually, it’s either resolved (meaning the task is done) or rejected (if the task failed). Once a Promise is resolved or rejected, it’ll remain in that state forever, and its callbacks will never fire again.

    You can attach callbacks to the Promise, which will fire when the Promise is resolved or rejected. And you can add more callbacks whenever you want – even after the Promise has been resolved/rejected! (In that case, they’ll fire immediately.)

    Plus, you can combine Promises logically into new Promises. That makes it trivially easy to write code that says, “When all of these things have happened, do this other thing.”

    And that’s all you need to know about Promises in the abstract. There are several JavaScript implementations to choose from. The two most notable are Kris Kowal’s q, based on the CommonJS Promises/A spec, and jQuery Promises (added in jQuery 1.5). Because of jQuery’s ubiquity, we”ll use its implementation in this tutorial.


    Making Promises with $.Deferred

    Every jQuery Promise begins with a Deferred. A Deferred is just a Promise with methods that allow its owner to resolve or reject it. All other Promises are “read-only” copies of a Deferred; we’ll talk about those in the next section. To create a Deferred, use the $.Deferred() constructor:

    A Deferred is just a Promise with methods that allow its owner to resolve or reject it.

    var deferred = new $.Deferred();
    
    deferred.state();  // "pending"
    deferred.resolve();
    deferred.state();  // "resolved"
    deferred.reject(); // no effect, because the Promise was already resolved
    

    (Version note: state() was added in jQuery 1.7. In 1.5/1.6, use isRejected() and isResolved().)

    We can get a “pure” Promise by calling a Deferred’s promise() method. The result is identical to the Deferred, except that the resolve() and reject() methods are missing.

    var deferred = new $.Deferred();
    var promise = deferred.promise();
    
    promise.state();  // "pending"
    deferred.reject();
    promise.state();  // "resolved"
    

    The promise() method exists purely for encapsulation: If you return a Deferred from a function, it might be resolved or rejected by the caller. But if you only return the pure Promise corresponding to that Deferred, the caller can only read its state and attach callbacks. jQuery itself takes this approach, returning pure Promises from its AJAX methods:

    var gettingProducts = $.get("/products");
    
    gettingProducts.state();  // "pending"
    gettingProducts.resolve;  // undefined
    

    Using the -ing tense in the name of a Promise makes it clear that it represents a process.


    Modeling a UI Flow With Promises

    Once you have a Promise, you can attach as many callbacks as you like using the done(), fail(), and always() methods:

    promise.done(function() {
      console.log("This will run if this Promise is resolved.");
    });
    
    promise.fail(function() {
      console.log("This will run if this Promise is rejected.");
    });
    
    promise.always(function() {
      console.log("And this will run either way.");
    });
    

    Version Note: always() was referred to as complete() before jQuery 1.6.

    There’s also a shorthand for attaching all of these types of callbacks at once, then():

    promise.then(doneCallback, failCallback, alwaysCallback);
    

    Callbacks are guaranteed to run in the order they were attached in.

    One great use case for Promises is representing a series of potential actions by the user. Let’s take a basic AJAX form, for example. We want to ensure that the form can only be submitted once, and that the user receives some acknowledgement when they submit the form. Furthermore, we want to keep the code describing the application’s behavior separate from the code that touches the page’s markup. This will make unit testing much easier, and minimize the amount of code that needs to be changed if we modify our page layout.

    // Application logic
    var submittingFeedback = new $.Deferred();
    
    submittingFeedback.done(function(input) {
      $.post("/feedback", input);
    });
    
    // DOM interaction
    $("#feedback").submit(function() {
      submittingFeedback.resolve($("textarea", this).val());
    
      return false;  // prevent default form behavior
    });
    submittingFeedback.done(function() {
      $("#container").append("<p>Thank you for your feedback!</p>");
    });
    

    (We’re taking advantage of the fact that arguments passed to resolve()/reject() are forwarded verbatim to each callback.)


    Borrowing Promises From the Future

    pipe() returns a new Promise that will mimic any Promise returned from one of the pipe() callbacks.

    Our feedback form code looks good, but there’s room for improvement in the interaction. Rather than optimistically assuming that our POST call will succeed, we should first indicate that the form has been sent (with an AJAX spinner, say), then tell the user whether the submission succeeded or failed when the server responds.

    We can do this by attaching callbacks to the Promise returned by $.post. But therein lies a challenge: We need to manipulate the DOM from those callbacks, and we’ve vowed to keep our DOM-touching code out of our application logic code. How can we do that, when the POST Promise is created within an application logic callback?

    A solution is to “forward” the resolve/reject events from the POST Promise to a Promise that lives in the outer scope. But how do we do that without several lines of bland boilerplate (promise1.done(promise2.resolve);…)? Thankfully, jQuery provides a method for exactly this purpose: pipe().

    pipe() has the same interface as then() (done() callback, reject() callback, always() callback; each callback is optional), but with one crucial difference: While then() simply returns the Promise it’s attached to (for chaining), pipe() returns a new Promise that will mimic any Promise returned from one of the pipe() callbacks. In short, pipe() is a window into the future, allowing us to attach behaviors to a Promise that doesn’t even exist yet.

    Here’s our new and improved form code, with our POST Promise piped to a Promise called savingFeedback:

    // Application logic
    var submittingFeedback = new $.Deferred();
    var savingFeedback = submittingFeedback.pipe(function(input) {
      return $.post("/feedback", input);
    });
    
    // DOM interaction
    $("#feedback").submit(function() {
      submittingFeedback.resolve($("textarea", this).val());
    
      return false;  // prevent default form behavior<br/>
    });
    
    submittingFeedback.done(function() {
      $("#container").append("<div class="spinner">");
    });
    
    savingFeedback.then(function() {
      $("#container").append("<p>Thank you for your feedback!</p>");
    }, function() {
      $("#container").append("<p>There was an error contacting the server.</p>");
    }, function() {
      $("#container").remove(".spinner");
    });
    

    Finding the Intersection Of Promises

    Part of the genius of Promises is their binary nature. Because they have only two eventual states, they can be combined like booleans (albeit booleans whose values may not yet be known).

    The Promise equivalent of the logical intersection (AND) is given by $.when(). Given a list of Promises, when() returns a new Promise that obeys these rules:

    1. When all of the given Promises are resolved, the new Promise is resolved.
    2. When any of the given Promises is rejected, the new Promise is rejected.

    Any time you’re waiting for multiple unordered events to occur, you should consider using when().

    Simultaneous AJAX calls are an obvious use case:

    $("#container").append("<div class='spinner'>");
    $.when($.get("/encryptedData"), $.get("/encryptionKey")).then(function() {
      // both AJAX calls have succeeded
    }, function() {
      // one of the AJAX calls has failed
    }, function() {
      $("#container").remove(".spinner");
    });
    

    Another use case is allowing the user to request a resource that may or may not have already be available. For example, suppose we have a chat widget that we’re loading with YepNope (see Easy Script Loading with yepnope.js)

    var loadingChat = new $.Deferred();
    yepnope({
      load: "resources/chat.js",
      complete: loadingChat.resolve
    });
    
    var launchingChat = new $.Deferred();
    $("#launchChat").click(launchingChat.resolve);
    launchingChat.done(function() {
      $("#chatContainer").append("<div class='spinner'>");
    });
    
    $.when(loadingChat, launchingChat).done(function() {
      $("#chatContainer").remove(".spinner");
      // start chat
    });
    

    Conclusion

    Promises have proven themselves to be an indispensable tool in the ongoing fight against async spaghetti code. By providing a binary representation of individual tasks, they clarify application logic and cut down on state-tracking boilerplate.

    If you’d like to know more about Promises and other tools for preserving your sanity in an ever more asynchronous world, check out my upcoming eBook: Async JavaScript: Recipes for Event-Driven Code (due out in March).


  • Tue, 21 Feb 2012 17:41:02 +0000: PDO vs. MySQLi: Which Should You Use? - Nettuts+

    When accessing a database in PHP, we have two choices: MySQLi and PDO. So what should you know before choosing one? The differences, database support, stability, and performance concerns will be outlined in this article.


    Summary

    PDO MySQLi
    Database support 12 different drivers MySQL only
    API OOP OOP + procedural
    Connection Easy Easy
    Named parameters Yes No
    Object mapping Yes Yes
    Prepared statements
    (client side)
    Yes No
    Performance Fast Fast
    Stored procedures Yes Yes

    Connection

    It’s a cinch to connect to a database with both of these:

    // PDO
    $pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password');
    
    // mysqli, procedural way
    $mysqli = mysqli_connect('localhost','username','password','database');
    
    // mysqli, object oriented way
    $mysqli = new mysqli('localhost','username','password','database');
    	

    Please note that these connection objects / resources will be considered to exist through the rest of this tutorial.


    API Support

    Both PDO and MySQLi offer an object-oriented API, but MySQLi also offers a procedural API – which makes it easier for newcomers to understand. If you are familiar with the native PHP MySQL driver, you will find migration to the procedural MySQLi interface much easier. On the other hand, once you master PDO, you can use it with any database you desire!


    Database Support

    The core advantage of PDO over MySQLi is in its database driver support. At the time of this writing, PDO supports 12 different drivers, opposed to MySQLi, which supports MySQL only.

    To print a list of all the drivers that PDO currently supports, use the following code:

    var_dump(PDO::getAvailableDrivers());

    What does this mean? Well, in situations when you have to switch your project to use another database, PDO makes the process transparent. So all you’ll have to do is change the connection string and a few queries – if they use any methods which aren’t supported by your new database. With MySQLi, you will need to rewrite every chunk of code – queries included.


    Named Parameters

    This is another important feature that PDO has; binding parameters is considerably easier than using the numeric binding:

    $params = array(':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600);
    
    $pdo->prepare('
    	SELECT * FROM users
    	WHERE username = :username
    	AND email = :email
    	AND last_login > :last_login');
    
    $pdo->execute($params);

    …opposed to the MySQLi way:

    $query = $mysqli->prepare('
    	SELECT * FROM users
    	WHERE username = ?
    	AND email = ?
    	AND last_login > ?');
    
    $query->bind_param('sss', 'test', $mail, time() - 3600);
    $query->execute();

    The question mark parameter binding might seem shorter, but it isn’t nearly as flexible as named parameters, due to the fact that the developer must always keep track of the parameter order; it feels “hacky” in some circumstances.

    Unfortunately, MySQLi doesn’t support named parameters.


    Object Mapping

    Both PDO and MySQLi can map results to objects. This comes in handy if you don’t want to use a custom database abstraction layer, but still want ORM-like behavior. Let’s imagine that we have a User class with some properties, which match field names from a database.

    class User {
    	public $id;
    	public $first_name;
    	public $last_name;
    
    	public function info()
    	{
    		return '#'.$this->id.': '.$this->first_name.' '.$this->last_name;
    	}
    }

    Without object mapping, we would need to fill each field’s value (either manually or through the constructor) before we can use the info() method correctly.

    This allows us to predefine these properties before the object is even constructed! For isntance:

    $query = "SELECT id, first_name, last_name FROM users";
    
    // PDO
    $result = $pdo->query($query);
    $result->setFetchMode(PDO::FETCH_CLASS, 'User');
    
    while ($user = $result->fetch()) {
    	echo $user->info()."\n";
    }
    // MySQLI, procedural way
    if ($result = mysqli_query($mysqli, $query)) {
    	while ($user = mysqli_fetch_object($result, 'User')) {
    		echo $user->info()."\n";
    	}
    }
    // MySQLi, object oriented way
    if ($result = $mysqli->query($query)) {
    	while ($user = $result->fetch_object('User')) {
    		echo $user->info()."\n";
    	}
    }
    


    Security

    Both libraries provide SQL injection security, as long as the developer uses them the way they were intended (read: escaping / parameter binding with prepared statements).

    Lets say a hacker is trying to inject some malicious SQL through the ‘username’ HTTP query parameter (GET):

    $_GET['username'] = "'; DELETE FROM users; /*"

    If we fail to escape this, it will be included in the query “as is” – deleting all rows from the users table (both PDO and mysqli support multiple queries).

    // PDO, "manual" escaping
    $username = PDO::quote($_GET['username']);
    
    $pdo->query("SELECT * FROM users WHERE username = $username");
    
    // mysqli, "manual" escaping
    $username = mysqli_real_escape_string($_GET['username']);
    
    $mysqli->query("SELECT * FROM users WHERE username = '$username'");
    

    As you can see, PDO::quote() not only escapes the string, but it also quotes it. On the other side, mysqli_real_escape_string() will only escape the string; you will need to apply the quotes manually.

    // PDO, prepared statement
    $pdo->prepare('SELECT * FROM users WHERE username = :username');
    $pdo->execute(array(':username' => $_GET['username']));
    
    // mysqli, prepared statements
    $query = $mysqli->prepare('SELECT * FROM users WHERE username = ?');
    $query->bind_param('s', $_GET['username']);
    $query->execute();
    

    I recommend that you always use prepared statements with bound queries instead of PDO::quote() and mysqli_real_escape_string().


    Performance

    While both PDO and MySQLi are quite fast, MySQLi performs insignificantly faster in benchmarks – ~2.5% for non-prepared statements, and ~6.5% for prepared ones. Still, the native MySQL extension is even faster than both of these. So if you truly need to squeeze every last bit of performance, that is one thing you might consider.


    Summary

    Ultimately, PDO wins this battle with ease. With support for twelve different database drivers (eighteen different databases!) and named parameters, we can ignore the small performance loss, and get used to its API. From a security standpoint, both of them are safe as long as the developer uses them the way they are supposed to be used (read: prepared statements).

    So if you’re still working with MySQLi, maybe it’s time for a change!


  • Mon, 20 Feb 2012 22:15:58 +0000: The Largest jQuery Class in the World - Nettuts+

    A couple weeks ago, Tuts+ Premium launched a free new real-time course, called “30 Days to Learn jQuery.” After signing up, each member receives an email, linking to a new video lesson for an entire month.

    I’m pleased to announce that, after only two weeks into the course, we’ve amassed the largest jQuery class in the world, with 40,000 registered students!


    You Can Still Sign Up

    If you never got around to signing up for the course, you still can; there’s no deadline. Even after I publish the final “Lesson 30,” the course will continue to be freely available forever.

    The Largest jQuery Class in the World

    For those of you who have some experience with jQuery, the final two weeks of the course will focus on higher level concepts, such as templating, code organization, deferreds, and much more. It’s okay to jump ahead, if you already know the essentials!


  • Sat, 18 Feb 2012 14:39:54 +0000: Nettuts+ Quiz #10: Basic CSS3 Techniques - Nettuts+

    In 2012, we plan to take our quizzes to a whole new level with ones aimed at all languages and catering to all competencies and tastes. This month, we’re covering some basic concepts and techniques in CSS3.

    The prime focus today is on the easier, more accessible portions of CSS3. If you’re a hardcore CSS3 fan, don’t worry — transitions, animations, gradients and media queries are on the way!




  • Thu, 16 Feb 2012 22:39:21 +0000: How to Upload Files with Ease Using DragonFly: New on Premium - Nettuts+

    File uploads are generally a tricky area in web development. In this Tuts+ Premium tutorial, we will learn how to use Dragonfly, a powerful Ruby gem that makes it easy and efficient to add any kind of upload functionality to a Rails project.

    Become a Premium member to read this tutorial, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network.


    What We’re Going to Build

    Our sample application will display a list of users, and for each one of them, we will be able to upload an avatar and have it stored. Additionally, Dragonfly will allow us to:

    • Dynamically manipulate images without saving additional copies
    • Leverage HTTP caching to optimize our application load

    Additionally, in this lesson, we will follow a BDD [Behavior Driven Development] approach, using Cucumber and RSpec.


    Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.