Using async await with jQuery’s $.ajax

Photo by Denys Nevozhai on Unsplash

If you’re like me, you’re probably stuck using jQuery more often than not. It’s everywhere, and to be honest it’s a solid, mature library. It’s also often already loaded on the page, especially if you’re working with WordPress.

Outside of DOM manipulations (which you can now do mostly with native JS), jQuery’s $.ajax() method is really handy and works well.

But did you know that this function provides Promise interface out of the box? I recently remembered this and I thought to myself:

Hmm I wonder if I can use async/await with jQuery’s $.ajax().

Turns out, you can!

The setup

Async/await is really new still, it’s only in the ES2017 spec, so you’ll need to use a transpiler like Babel to get it working in older browsers. Most of us are using Babel anyway with our bundlers (Webpack, Browserify), so this isn’t a huge deal.

Assuming you already have Babel installed and configured, the first thing you’ll need to do is get Babel to use the ‘env’ preset. In your .babelrc file, add these lines:

{
...
"presets": ["babel-preset-env"],
...
}

You’ll also have to install this Babel preset and polyfill from npm: npm i -D babel-preset-env babel-polyfill.

Once that’s done you’ll also need to install this magic plugin for Babel: npm i -D babel-plugin-transform-async-to-generator. This is the key package that lets you use async/await in your code. I should mention that this simply gets Babel to compile the async/await syntax to ES2015 generators, so if you’re not targeting most modern browsers keep that in mind.

The next, and FINAL thing you need to do is use the babel-polyfill module in your code. You can use a Webpack loader if you like, or just include the package in your source files:

import 'babel-polyfill';

Phew!

Ok, now we’re ready to go. Start up Webpack and let’s start using async/await!

Don’t call me, maybe

Back in the day you had to use $.ajax() like this:


//Function wrapper that confuses alot of devs because async code works differently function doAjax() { $.ajax({ url: ajaxurl, type: 'POST', data: { stuff: "here" }, success: function (data) { //wacky nested anonymous callbacks go here var something_but_not_really = data; }, error: function (jqXHR, textStatus, errorThrown) { // Empty most of the time... } }); return something_but_not_really }

I know when I was a junior dev I had no idea why something_but_not_really was undefined. I had to learn about callbacks a billion times 😬.

But now…

async function doAjax(args) {


    const result = await $.ajax({
        url: ajaxurl,
        type: 'POST',
        data: args
    });

    return result;
}

And result actually returns the AJAX result. Cool right?

The big benefit of async/await is that it makes asynchronous code appear synchronous. As in, do this thing, wait for it to finish and then give me the result.

Errors

Notice anything missing in our new function? Yep, error handling is non-existent. Fortunately, since async/await is essentially synchronous, you can use try...catch()!!!

async function doAjax(args) {
    let result;

    try {
        result = await $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: args
        });

        return result;
    } catch (error) {
        console.error(error);
    }
}

And there you have it. Some error catching built in. Now, there’s other ways to handle errors with async/await, but they’re a little more complex.

The other thing to keep in mind now, since we’re returning the result of an awaited function, result will equal a Promise instance. You have 2 options with what you can do with the result.

The first option is to make sure that you use await when calling doAjax() later on.

// Elsewhere in code, inside an async function
const stuff = await doAjax();

The other option is to use the Promise interface and roll that way:

doAjax().then( (data) => doStuff(data) )

Promises aren’t all that bad, and can look cleaner or be easier to work with, depending. I’ve found that using ES2015 classes it’s sometimes easier to use the Promise interface, so YMMV.

But that’s it – go get your $.ajax() using async/await today!

JavaScript’s cryptic ‘this’ – what, when and why

*Photo by Tarun Ram on Unsplash

Before MDN started to organize their JavaScript documentation, finding answers to your JavaScript questions often landed you on Stack Overflow.

Welp, these days MDN has mostly done away with that practice, that is, except if you’re looking for answers around the usage of JavaScript’s this keyword.

The documentation is great, it really is, but it’s not exactly full of helpful, real-world examples. So I thought I’d put together a few tips and tricks about the ever so magical this keyword.

Old-skool JS

“Back in my day we had to alert out our objects!”

Ok, so yeah, if you run console.log(this) in your dev console you’ll generally see that by default, this = Window{}. Super helpful…😏

It gets more interesting when you check the value of this inside a function:

function mahFunc(){
    console.log(this);
}

mahFunc();
// Window{}

You should still see the Window object. Ok so, nothing new here.

But what if you add 'use strict'?

function mahFunc(){
    'use strict'
    console.log(this);
}
// undefined

Hmm.

Ok now, but what if you call mahFunc() on the Window global (since it’s a global function)?

function mahFunc(){
    'use strict'
    console.log(this);
}

window.mahFunc();
// Window

Huh?

Strict mode is a funny beast, but it generally makes errors more obvious and cleans up your JavaScript. Something not mentioned in the MDN docs is that bundlers/loaders/concatenators like Webpack/Browserify, may have strict mode enabled by default. You might end up with some wacky loader that enables it with out you knowing. So keep an eye out if you ever see your this call returning something funny.

Call me plz

Ok so this in a global context is weird, but who doesn’t use objects and ES2015 classes these days? If you’d like to use a different value for this, (as-in not undefined or Window) inside your function, you can pass a context with .call() and .apply(). I always remember these with ‘yadda-yadda.prototype.call()’.

function mahFunc(){
    console.log(this);
}

const config = {

    stepOne(){
        //do step one
    },

    stepTwo(){
        //do step 2
    }
}

mahFunc.call(config);

//{stepOne: ƒ, stepTwo: ƒ}

And there you go. this references the object passed in argument to .call(). Cool right?

This way you’re able to specify a context for a function. It’s super handy and what a lot of frameworks and bundlers use internally – check out your Webpack bundles!

I won’t go over all the possible cases/uses of this, there’s quite a few and the MDN doc is really good.

It’s important to remember this 🙄.

JavaScript build tooling and the CLI

Something that’s come up recently in the front-end world is the topic of a learning curve and JavaScript tooling such and Webpack and Babel. While I agree that new tooling can sometimes be a pain to learn, since when did being a web developer/programmer/rockstar not require learning new things? I mean, learning the CLI is one thing, but it’s not suuuuper difficult and is definitely a skill that will serve you well in your career. On top of that, front-end build tooling has been around for a while, first with Grunt and then Gulp. Does Webpack make things that much more difficult?

The argument I’m making is partially around React and how Webpack (or similar) is required. To me, this doesn’t seem like a problem, as many languages require compilation during a build step. I see the build step and associated tooling a good thing, as it allows for more streamlined and complex programming concepts to be brought into front-end development.

If you’re worried about learning something like the Webpack build process, Create React App has got all the setup jank covered. In Vue, there’s vue-cli which similarly gets you set up. In both cases all it takes to get up and running is npm install then npm start. That’s not too bad!

I guess what I’m saying, if all this ‘new’ stuff bothers you as a developer, it might be time to 1.) upgrade your skills, or 2.) do something else. Things aren’t slowing down any time soon in the front-end landscape, better get on the wagon or jump off!

WordPress Jetpack contact forms – AJAX

EDIT, May 9, 2016

I noticed that the form wouldn’t submit when not logged in, so I’ve updated the gist to include a check to see if a user is logged in. 


Jetpack is awesome for a lot of things. Unfortunately, one of the things that it isn’t so great for is submitting it’s contact form via AJAX. I’ve looked into this before and decided I might as well hack something together that ‘kind of works’ ™.

Here’s the full working code, I’ll go into a bit below:

https://gist.github.com/ptasker/7606fac1f75cfa99dc7d25dc178479f4

Basically, all you do is fake-send the form via ajax, parse the returned page’s HTML and look for an H3 tag with the submission message.

Easy-peasy…