Ajax from scratch

Julien Muetton

API Hours CFE

2013 April, 3rd

Summary

History

What is AJAX?

Asynchronous JavaScript and XML

ECMAScript HTTP API

Request data from server without page reload

Javascript to request data

XMLHttpRequest object.

Normalize communications

XML or JSON formatted.

Typical call

Browser->Server: Asks a page Note Right of Server: Compute the page Server->Browser: Returns HTML Note Left of Browser: User interacts\nwith the page Browser-->Server: Asks for data Note Right of Server: Looks for data Server-->Browser: returns data in JSON, XML... Note Left of Browser: Data are processed\nthrough callback

XMLHttpRequest

XMLHttpRequest

Can be Synchronous or asynchronous

Yes Indeed...

Single object for Request and Response

Implementation evolved over the years.

Cross browser creation

function createXhrObject() {
    if (window.XMLHttpRequest)
        return new XMLHttpRequest();

    if (window.ActiveXObject) {
        var names = [
            "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0",
            "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"
        ];
        for(var i in names) {
            try{ return new ActiveXObject(names[i]); }
            catch(e){}
        }
    }
    window.alert("XMLHTTPRequest isn't supported.");
    return null;
}
xhr = createXhrObject();

XMLHttpRequest: Request

Prepare

Send

Abort

XMLHttpRequest: Response

Read status

Access server response

Response headers

Event driven: Old way

A single event: onreadystatechange

Sample usage

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
    switch (this.readyState) {
        case this.LOADING:
            // Use this for long polling
            break;

        case this.DONE:
            if (/^2/.test(this.status)) {
                // success
            } else {
                // failure
            }
    }
}

xhr.open('GET', 'http://example.org/ressources/1');
xhr.send();

Event driven: New way

introduced in XMLHttpRequest Level 2, 25 February 2008

Attach event listeners through addEventListener(name, callback);

Sample usage

var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function () {
    if (/^2/.test(xhr.status)) {
        // success
    } else {
        // failure
    }
}
xhr.addEventListener('error', function () {
    // something went wrong
}
xhr.addEventListener('progress', function () {
    // Use for long polling
}

xhr.open('GET', 'http://example.org/ressources/1');
xhr.send();

Promise API: leverage asynchronous

Promise?

Quick jQuery example

jQuery is none of CommonJS Promize compliant but is consistent.

$.ajax( "/example" )

    // when request is successful
    .done(function(response) { alert("success"); })

    // Error happened
    .fail(function(xhr, statusText, error) {
        alert("error"); })

    // executed in both cases
    .always(function() { alert("complete"); });

Combine

Note there is a single callback to handle all returned data.

$.when(
    $.ajax("/example"),
    $.ajax("/sample")
)

// called when both succeed
.done(function (example, sample) {
    alert ('both returned');
})

// called when any request fails
.fail(function () { /* ... */ });

Pipe

$.ajax( "/example" )
    .fail(function () {
        alert('example failed')
    })
    .pipe(
        function success(example) {
            return $.ajax('/sample');
        },
        function error() {
            alert('example failed !')
        })

    // From here, this is about second request
    .done(function (sample) {
        alert ('sample returned');
    })
    .fail(function () {
        alert('sample failed')
    });

Filter data

Easy way to tweak inconsistant apis.

$.ajax( "/example" )
    .then(
        function success(example) {
            // filter data
            return {response: example};
        },
        function error() { /*...*/ },
        function progress() { /*...*/ }
    )

    // `data` has been altered by `then` callback
    .done(function (data) {
        console.log(data.response);
    });

What's next?

Questions?

Thank you

/

@themouette