Overcoming Scope Limitations in jQuery AJAX Callbacks

Update: Not long after writing this post, I realized that $.ajax() has a configuration option named context, which allows you to assign scope to a callback method. This knowledge renders the specifics of what I say below pretty much irrelevent, but closures remain a very slick solution to scoping problems in other situations.

If learning jQuery is teaching me anything, it’s the power of closures.  Recently I’ve been working on a jQuery-powered gallery for a client.  My code dynamically retrieves JSON data from the server. The problem is that such a construct as the one below doesn’t work:

Gallery = function(id)
{
    this.id = id;
 
    this.loadGallery = function()
    {
        $.ajax({
            'url' : '/gallery.php',
            'data' : { 'gallery_id' : this.id },
            'dataType' : 'json',
            'success' : this.populate
        });
    };
 
    this.populate = function(data)
    {
        // populate() gets called, but not in the scope of the Gallery object.
        // So the following call will output "undefined".
        alert(this.id);
    };
};

Unfortunately jQuery doesn’t provide us with a mechanism to set the scope of our callbacks like some frameworks but fortunately for us JavaScript provides a way around that: the closure.

Gallery = function(id)
{
    // ...
 
    this.loadGallery = function()
    {
        $.ajax({
            'url' : '/gallery.php',
            'data' : { 'gallery_id' : this.id },
            'dataType' : 'json',
            'success' : function(gallery) {
                return function(data) { gallery.populate(data) };
            }(this)
        });
    };
 
    // ...
};

What the heck does this all mean? In JavaScript it’s completely legal to create an anonymous function (also known as a closure) and call it, all in a single statement. So:

function(gallery){ ... }(this)

creates an anonymous function and immediately calls it, passing this, which is a reference to the Gallery instance on which the loadGallery is being called, as the first parameter to the function. What are we doing inside that function?

return function(data) { gallery.populate(data) };

Remember: in JavaScript everything is an Object including functions, so it’s completely legal for one function to return a reference to another function or, in this case, an anonymous function .

The closure being returned has a single argument named data, and because it is defined within the scope of the outer closure, we can gall methods on gallery, such as populate(). It’s a long way to go to resolve the scoping issue, but it does work.

The JavaScript Dollar Sign ($) – What’s It For?

My latest project involves some customized extensions to a WordPress based site.  The designer who outsourced the development to me requested a number of JavaScript-based effects, and though I’m aready familiar with a number of other JavaScript frameworks including Sencha (formerly ExtJS), WordPress ships with jQuery and so that’s the framework that we’ve decided to use.

Ever wonder what the heck the “$” means in jQuery or why it was chosen?  I sure did, and just found a great article explaining it.

Moving Posts Between Categories in WordPress

At some point or another, you may want to adjust the structure of categories in your WordPress blog.  I just ran into such a situation when a client who was previously managing two blogs (one for “News” and one for industry “Ramblings”) wanted to merge their two blogs into a single blog.  Using WordPress and a little bit of SQL, I’m going to teach you how to move posts in bulk to a new category. This tutorial assumes that you are using the default “wp_” table prefix, so make adjustments as neccessary; and as always, create a backup of your database before trying any of the steps below.

Step 1: Create the New Category

This step is easy.  Simply create the new category as you normally would from within WordPress.  After the category has been created, issue the following SQL against your WordPress database to determine the ID of the new category:

SELECT * FROM WP_Terms WHERE category_name = "New Category";

For me, this command told me that the id of my new category was 46, so I’ll remember that and continue to the next step.

Step 2: Find the ID of the Old Category

Now we need to do the same thing, but for the old category.  In my case I am moving all Uncategorized posts to the category I just created, so I need to find the unique ID of the “Uncategorized” category:

SELECT * FROM WP_TERMS WHERE CATEGORY_NAME = "Uncategorized";

This command tells me that “Uncategorized” has a unique id of “1”, so I’ll remember this value and continue.

Step 3: Update the Post/Category Relationship

In this step we’re finally modifying our database, so make sure you have a backup of your WordPress database before you continue.  We’re now going to update the relationship between the posts and the category.  The WP_TERM_RELATIONSHIPS table contains a list of post-to-category relationships.  The OBJECT_ID field specifies the unique id of the posts, the TERM_TAXONOMY_ID field specifies the unique ID of the category. So what we need to do is update any record with TERM_TAXONOMY_ID equal to the value from Step 2 to the ID of the table we created in Step 1:

UPDATE WP_TERM_RELATIONSHIPS SET TERM_TAXONOMY_ID = 46 WHERE TERM_TAXONOMY_ID = 1;

And voila! Your posts will now be treated as members of the new category.

Resetting Your WordPress Password

Bloggers: have you ever forgotten the password for one of your WordPress blogs?  Or attempted to take over or maintain a blog setup by someone else who doesn’t know the admin password?  This is your lucky day!

Assuming you have access to the database containing the WordPress blog’s data, resetting the password is easy. Assuming that the blog is using the default “wp_” table prefix, the user account is named “admin,” and the new password is being reset to “password”:

UPDATE wp_users SET user_pass = MD5("password") WHERE user_login = "admin";

For more information about resetting a lost WordPress password, see the official page on the subject at the WordPress Codex.