Last Updated: February 25, 2016
· bhousman

Using jQuery Deferreds

Recently I was developing a contact modal with your standard input fields: First Name, Last Name, Email, and Message. In addition to this information, I wanted some extra metadata about the user to better color in the person who's contacting me.

http://smart-ip.net is a free web service which publishes basic info about the requesting IP address via their API endpoint. Data is returned via JSON for the requesting IP, which in my case is the person trying to contact me.

See for yourself by visiting this URL: http://smart-ip.net/geoip-json?callback=?

I was faced with a situation where I first needed to make a GET request for the above mentioned IP data and then a POST request to send my form data (as well as the IP data) to my server for processing. The challenge here is making two AJAX requests where the second is contingent on the result of the first.

Here's where jQuery Deferreds come into play. As you can see below, I setup an object literal consisting of the form input values (NOTE: it's good practice to perform client-side validation before POSTing this data to your web server for processing. What I'm displaying is merely for quick and easy example purposes.)

What happens from here is an XHR request is made to the IP web service and after this transaction returns a response, the second XHR request is made which is what POSTs the form data to my /contact route.

!function() {

  document.querySelector('input[type="submit"]').onclick = function(e) {

    var contactInfo = {
      firstName: document.querySelector('input[name="firstName"]').value.trim(),
      lastName: document.querySelector('input[name="lastName"]').value.trim(),
      email: document.querySelector('input[name="email"]').value.trim(),
      message: document.querySelector('textarea[name="message"]').value.trim(),
      ip: null,
      long: null,
      lat: null

    function updateContactInfo(data) {
      contactInfo.ip = data.host;
      contactInfo.long = data.longitude;
      contactInfo.lat = data.latitude;

      url: 'http://smart-ip.net/geoip-json?callback=?',
      type: 'GET',
      dataType: 'json',
    }).done(function(data) {
        url: '/contact',
        data: contactInfo,
        type: 'POST',
        dataType: 'json'