Tag Archives: AJAX

MEAN web development #6: AngularJS in the front

Hi all and welcome back! Welcome back to me too as I’ve been away for a while. Let’s just say I was enjoying a summer vacation from blogging. But I’m back to finish this MEAN series! This week I’ve got AngularJS for you. Maybe next week too.
And in case you need a refresher, here are my previous posts about MEAN:

  1. MEAN web development #1: MEAN, the what and why
  2. MEAN web development #2: Node.js in the back
  3. MEAN web development #3: More Node.js
  4. MEAN web development #4: All aboard the Node.js Express!
  5. MEAN web development #5: Jade and Express
  6. MEAN web development #6: AngularJS in the front
  7. MEAN web development #7: MongoDB and Mongoose
  8. MEAN web development #8: Sockets will rock your socks!
  9. MEAN web development #9: Some last remarks

So in the previous post we’ve seen how we can build pages using the Jade template engine. Pretty sweet, but we need something bigger, better and badder for our front-end.

You can find the examples for this blog on my GitHub page in the mean6-blog repository.

What is AngularJS?

You may have heard of AngularJS before. It’s one of the most popular open-source front-end JavaScript frameworks for the web developed by Google. And, of course, it’s the A in MEAN. But what does it do?

AngularJS is an MVVM framework, much like Knockout.js. It does a bit more than Knockout.js does though. Next to bindings AngularJS can be used for DOM manipulation, more like jQuery. And it does even more, like handling AJAX and routing. As Google likes to put it: AngularJS is “Superheroic” in that it does just about everything.

So instead of talking let’s see some action! First of all we need to install AngularJS. You can download it from the AngularJS website, or you can install it through a package manager such as npm or Bower (install angular). I’ve discussed all three methods in earlier posts so I will not repeat them here. Anyway, if you’ve downloaded my samples from GitHub you’ll be good to go.

The first examples of this post can be tested using nothing but the file system. For later examples with AJAX we’re going to need a little Node.js server, so I’ll add that later. The non-server examples can be found in the front-end.html and the front-end.js files.

So let’s take a look at a first example.

<html>
    <head>
        <meta charset="utf-8">
        <title>AngularJS example</title>
        <script src="node_modules/angular/angular.min.js"></script>
    </head>
    <body ng-app>
        <p>This is your first angular expression: {{ 'This is AngularJS' + ' syntax!' }}</p>
    </body>
</html>

So there are two things going on here. First is the ng-app directive in the body element. This tells AngularJS that body is the root element of our application and that AngularJS should do its magic. You can place it anywhere you want (like in the html element, or maybe a div element somewhere) and a page can have multple ng-app directives (which I won’t be doing in this post).

Next is, of course, the weird {{ }} syntax, which is the syntax AngularJS uses for its bindings. In this case you’ll see that ‘This is AngularJS’ and ‘ syntax!’ are, indeed, appended in your browser, like it was just some JavaScript. Try using {{ 1 + 2 }} and you’ll see it will print ‘3’ since 1 + 2 equals 3 in JavaScript (and not ’12’).

Now let’s look at something really very cool. Suppose you want to bind some value to an input. Here’s how to do it.

<body ng-app>
    <p>Enter you name:
        <input type="text" ng-model="firstName" />
        <input type="text" ng-model="lastName" />
    </p>
    <p>You have entered: {{ firstName + ' ' + lastName }}</p>
</body>

No JavaScript required! Wow, that is so cool! And firstName and lastName are updated real time, while you’re typing! We bound our inputs using the ng-model directive which takes care of creating and binding the firstName and lastName properties.

Enter controllers

You’ll often want more control over your code and putting all of your JavaScript into your HTML is not a good idea. So we’ll want to use AngularJS with some custom JavaScript file that we wrote. This is where things get tricky. Not very tricky, but you just got to know how it works.

An AngularJS application is defined by modules. Modules then define controllers.

angular.module('fullNameApp', [])
    .controller('fullNameController', function ($scope) {
        $scope.firstName = '';
        $scope.lastName = '';
        $scope.fullName = function () {
            return $scope.firstName + ' ' + $scope.lastName;
        };
    });

So as we see here we create a module by calling the angular.module function and passing it more than one parameter. This returns an application so we can call the controller function directly on the return value. In the controller function we pass in the name of the controller, so we can use it in our HTML, and a constructor function, which receives a $scope variable to which we can append properties.

Now our HTML would look like this:

<html>
    <head>
        <meta charset="utf-8">
        <title>AngularJS example</title>
        <script src="node_modules/angular/angular.min.js"></script>
        <script src="front-end.js"></script>
    </head>
    <body ng-app="fullNameApp">
        <div ng-controller="fullNameController">
            <p>Enter you name:
                <input type="text" ng-model="firstName" />
                <input type="text" ng-model="lastName" />
            </p>
            <p>You have entered: {{ fullName() }}</p>
        </div>
    </body>
</html>

So as you can see we’ve now named our ng-app directive and we’ve added a div element with an ng-controller directive which points to our fullNameController controller. Finally, we now use the fullName function. Notice that we could now set default values in our controller and they’ll be displayed on our page automatically.

$scope.firstName = 'Sander';
$scope.lastName = 'Rossel';

More directives

So let’s take a look at some more directives that can help you build amazing pages. ng-repeat can be used to repeat an element for every item in a list. So let’s add a little array on our controller.

$scope.favoriteMovies = [
    'Star Wars',
    'Lord of the Rings',
    'Fight Club'
];

And display it in an unordered list.

<ul>
    <li ng-repeat="movie in favoriteMovies">
        {{ movie }}
    </li>
</ul>

Now we want to be able to add and delete items from the list. This next piece might blow your mind, but there’s a very simple directive to make a text input that can make a comma separated list and convert it to an array real time.

<input type="text" ng-model="favoriteMovies" ng-list />

So we bind the input to our favoriteMovies using ng-model and then use ng-list to convert it to a comma separated list. Try adding “, Pulp Fiction” (or whatever movie you like) to the text input and the movie will automatically be added to the unordered list we had before!
And if you want something else instead of a comma specifiy it in the ng-list, like so:

<input type="text" ng-model="favoriteMovies" ng-list=" | " />

And what if we add objects instead of strings?

$scope.favoriteAlbums = [
    { artist: 'The Beatles', title: "Sgt. Pepper's Lonely Hearts Club Band" },
    { artist: 'Moby', title: 'Play' },
    { artist: 'The Prodigy', title: 'Fat Of The Land' }
];
<ul>
    <li ng-repeat="album in favoriteAlbums">
        {{ album.artist + ' - ' + album.title }}
    </li>
</ul>

So how about making that editable?

<div ng-repeat="album in favoriteAlbums">
    <input type="text" ng-model="album.artist" />
    <input type="text" ng-model="album.title" />
</div>
<button ng-click="favoriteAlbums.push({})">New album</button>

And that’s where we see the ng-click in action. Of course we could’ve called a function on our controller too.

$scope.addAlbum = function () {
    $scope.favoriteAlbums.push({});
};
<button ng-click="addAlbum()">New album</button>

There’s a little problem with ng-repeat that isn’t quite obvious from these examples. ng-repeat creates a separate scope for each object in an array. For objects this is no problem, but if you were binding to an array of primitives, such as integers or strings, the values wouldn’t be updated. So just remember to use objects when wanting to update array elements.

So how about adding a little styling to our page? With the ng-class directive we can add styles to elements based on some boolean value. The best part is you can add multiple classes based on one or more boolean values. So I have added a little embedded CSS to our page.

<style>
    .colored {
        color: red;
    }
 
    .underlined {
        text-decoration: underline;
    }
</style>

And two properties in the controller to specify whether we want some text to be colored and/or underlined.

$scope.addColor = true;
$scope.addUnderline = false;

Now in our HTML we can add two checkboxes for the two properties above and then add an ng-class directive on some element that adds the CSS classes based on the JavaScript properties.

Color: <input type="checkbox" ng-model="addColor" />
Underline: <input type="checkbox" ng-model="addUnderline" />
<p ng-class="{ colored: addColor, underlined: addUnderline }">This text might be colored and/or underlined!</p>

Pretty sweet, right? As you can see ng-class should simply evaluate to an object where each property is a class name with a value true or false to specify whether it should be applied.

But there’s an alternative. We could simply specify a string too. So consider the next JavaScript function which returns a string:

$scope.getClasses = function () {
    var classes = '';
    if ($scope.addColor) {
        classes += 'colored ';
    }
    if ($scope.addUnderline) {
        classes += 'underlined ';
    }
    return classes;
};

We can now use ng-class as follows:

<p ng-class="getClasses()">This text might be colored and/or underlined!</p>

Or you could return an array where each element is either an object such as in the first method or a string such as in the second method. I’ll leave that as practice for the reader though.

Also fun to mention, when you’re inside an ng-repeat directive you can use ng-class-even and ng-class-odd which work exactly as ng-class, but apply the styles only to even or odd elements.

Filters

AngularJS had a feature called filters. It can format values or actually filter lists.

Let’s go back to the first example. Let’s suppose you wanted to show full name in just uppercase or in just lowercase. This is an easy task!

<p>You have entered: {{ fullName() | uppercase }}</p>
<p>You have entered: {{ fullName() | lowercase }}</p>

We can also use a filter to format numbers and dates. It looks kind of the same, except this time you throw in a format.

<p>
    <input type="text" ng-model="number"><br>
    Number (default): {{ number | number }}<br>
    Number (no fractions): {{ number | number: 0 }}<br>
    Number (three fractions): {{ number | number: 2 }}
</p>
<p>
    Date (default): {{ date | date }}<br>
    Date (dd-MM-yyyy): {{ date | date: 'dd-MM-yyyy' }}<br>
    Date (yy/M/d): {{ date | date: 'yy/M/d' }}<br>
    Date (full): {{ date | date: 'fullDate' }}<br>
    Date (long): {{ date | date: 'longDate' }}
</p>

And for arrays you can do some awesome stuff too!  For this we use the orderBy or filter filter.

<h3>Ordered by title</h3>
<ul>
    <li ng-repeat="album in favoriteAlbums | orderBy: 'title'">
        {{ album.artist + ' - ' + album.title }}
    </li>
</ul>
<h3>Ordered by artist reverse</h3>
<ul>
    <li ng-repeat="album in favoriteAlbums | orderBy: 'artist' : true">
        {{ album.artist + ' - ' + album.title }}
    </li>
</ul>
<h3>Filtered on everything with '*y*'</h3>
<ul>
    <li ng-repeat="album in favoriteAlbums | filter: 'y'">
        {{ album.artist + ' - ' + album.title }}
    </li>
</ul>
<h3>Filtered on artist with '*y*'</h3>
<ul>
    <li ng-repeat="album in favoriteAlbums | filter: { artist: 'y' }">
        {{ album.artist + ' - ' + album.title }}
    </li>
</ul>

Keep in mind that we can get these values from our JavaScript controller as well. You can make the most awesome dynamic filters with very little trouble. Just make sure you pass in an object with the same properties as the objects you’re repeating and set their values to the values you’d like to filter.

AJAX with AngularJS

So as mentioned AngularJS does a lot more than just HTML binding. One feature we’re going to look at here is that of the $http service. Needless to say we’ll need a little back-end server to communicate with, so for the AJAX examples I’m going to create a Node.js server and some new HTML and JavaScript so we can serve them up using our Node.js server.

Here’s the server:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();

var books = [
    { title: 'Lord of the Rings', author: 'J.R.R. Tolkien' },
    { title: 'Harry Potter', author: 'J.K. Rowling' },
    { title: "The Hitchhiker's Guide to the Galaxy", author: 'Douglas Adams' }
];

app.use(bodyParser.json());
app.use(express.static('public'));

app.get(['/', '/index'], function (req, res) {
    res.sendFile(__dirname + '/public/ajax-example.html');
});

app.get('/books', function (req, res) {
    res.send(books);
});

app.post('/addBook', function (req, res) {
    var book = req.body;
    books.push(book);
    res.send(books);
});

var server = app.listen(80, '127.0.0.1');

So there’s a lot going on there. First of all I’ve added some Express. I’m also requiring body-parser (npm install body-parser), which is needed to get our POST data. Then I call the app.use function a couple of times. We’ve seen it before. It simply adds a middleware to a path. In this case we tell it to parse any JSON body so we can use it in our app. We also tell it that we can serve static files from the public folder (so we can serve the HTML and JavaScript file).
After that we serve the page by browsing to the root or root/index. I’ve also specified a GET for root/books, which simply returns a list of books (as JSON). And, what it’s all about, a POST to add a book to the list of books.

Let’s look at our front-end JavaScript.

angular.module('ajaxApp', [])
    .controller('ajaxController', function ($scope, $http) {
        $scope.newAuthor = null;
        $scope.newTitle = null;
        $scope.books = [];
        $scope.getBooks = function () {
            $http.get('http://localhost/books')
            .then(function (response) {
                $scope.books = response.data;
            }, function (response) {
                alert('Something went wrong while getting the books!');
            });
        };
    $scope.addBook = function () {
        $http.post('http://localhost/addBook', { author: $scope.newAuthor, title: $scope.newTitle })
            .then(function (response) {
                $scope.newAuthor = null;
                $scope.newTitle = null;
                $scope.books = response.data;
            }, function (response) {
                alert('Something went wrong while adding a new book!');
            });
        };
    });

So that’s quite a thing too! First of all notice a $http parameter being passed to the controller constructor function. We’ll need this $http parameter to make HTTP calls. Now we first use this in the getBooks function. You’ll see that using this $http stuff is actually very simple! We use $http.get and pass it our URL to get the books. It returns a promise, which has a then function that takes two callbacks, a success function and a failure function. The functions are executed once the asynchronous call returns (AJAX is asynchronous, remember?). So if everything goes right we simply assign the data (a list of books) to the books property. If something goes wrong we show an alert.

In the addBook function I’m using the $http.post function. It’s really similar to the get example, except we’re now passing in some data, a new book. Upon success the book list, including the new book, is returned and we reset the newAuthor and newTitle (nice example of two-way binding by the way).

Now for the HTML:

<html>
    <head>
        <meta charset="utf-8">
        <title>AngularJS AJAX example</title>
        <script src="angular.min.js"></script>
        <script src="ajax-example.js"></script>
    </head>
    <body ng-app="ajaxApp">
        <div ng-controller="ajaxController">
 
            <h2>AJAX example</h2>
            <button ng-click="getBooks()">Get books</button>
            <ul>
                <li ng-repeat="book in books">
                    {{ book.author + ' - ' + book.title }}
                </li>
            </ul>
 
            <input type="text" ng-model="newAuthor" />
            <input type="text" ng-model="newTitle" />
            <button ng-click="addBook()">Add book</button>
        </div>
    </body>
</html>

And there you have it!

So AngularJS can do two-way binding, supports MVVM and MVC architecture, it can do AJAX, but also routing, internationalization and localization, you can write custom directives and customize all you like, it supports testing and it has lots of directives I haven’t discussed like ng-show, ng-hide, ng-form, ng-blur… I guess Google wasn’t exaggerating when they called AngularJS ‘superheroic’ because it really seems to have some super powers!

And of course I’ll be leaving you with some recommended reading. As you know I’m a big fan of the (free) Succinctly series by Syncfusion, so here’s two must reads: AngularJS Succinctly and Node.js Succinctly. Also check out these awesome books by Manning Publications: AngularJS In Action, AngularJS In Depth, Node.js In Action (Second Edition) and Getting MEAN. And a book I’ve recently picked up at work: Pro AngularJS.
Well, that should keep you busy for a few months!

Happy coding!

Web development #7: Dynamic page updates with AJAX

So in theory you should now have all the tools to create the most awesome websites. However, I don’t think any tutorial on web development is complete without doing some AJAX. No idea what I’m talking about? Read my previous posts.

  1. Web development #1: Internet and the World Wide Web
  2. Web development #2: Our first website using HTML
  3. Web development #3: Styling our page with CSS 3
  4. Web development #4: PHP in the back
  5. Web development #5: User input with HTML Forms
  6. Web development #6: Getting interactive with JavaScript
  7. Web development #7: Dynamic page updates with AJAX
  8. Web development #8: Where to go from here

So what is AJAX all about? It’s an abbreviation for Asynchronous JavaScript And XML. It enables us to send a request to the server and receive a result without having to refresh our entire page. Now that’s pretty awesome! What’s also pretty awesome is that we don’t need to use XML. As Linus Torvalds, creator of Linux, already said “XML is crap. Really. There are no excuses. XML is nasty to parse for humans, and it’s a disaster to parse even for computers. There’s just no reason for that horrible crap to exist.” So what we’ll be using is a form of AJAX called AJAJ, where the last J stands for JSON (JavaScript Object Notation). To make it a bit more confusing, we’ll just call it AJAX anyway. Oh yeah, and it doesn’t have to be asynchronous either…

JavaScript objects and JSON

First of all we need to know what JavaScript Objects are and what they look like. After that JSON will come naturally. So JavaScript has objects and much like objects in other languages JavaScript objects are just wrappers around certain functionality. The difficulty in JavaScript, of course, lies in that anything can be anything and then can become anything else… Let’s just look at an example.

// Creates an empty object.
var obj = {};
// Gives the object a firstName property.
obj.firstName = 'Sander';
// Gives the object a lastName property.
obj.lastName = 'Rossel';
// Gives the object a getFullName function.
obj.getFullName = function () {
    return this.firstName + ' ' + this.lastName;
};

// Alternative for the above.
var person = {
    firstName: 'Sander',
    lastName: 'Rossel',
    getFullName: function () {
        return this.firstName + ' ' + this.lastName;
    }
};

Now this wouldn’t be JavaScript if we didn’t have even more methods to create objects (JavaScript also knows constructors). We’re not interested in those though. What we’re interested in is the second method I’m using. Notice that, to create an object, we use curly braces. We can then basically add anything to that object by simply defining keys (property or function names) and values (default values for properties or implementations for functions) seperated by colons. Each key and value is seperated by a comma. And of course objects can contain other objects too.

var outerObj = {
    innerObj: {
        someValue: null
    },
    anotherInnerObj: {
        innerInnerObj: {}
    },
    message: 'Phew, what syntax!'
};

You can work with objects as ways of namespaces so you can keep the ‘global namespace’ clean and minimize the chance for name conflicts with other libraries. Objects are also often used to create some sort of options that are given to a function. A function then simply checks if some property or method on the option object exists, what its value is, and acts accordingly. We’ll see this usage a little later when working with AJAX.

So then, what is JSON? It’s simply some text using almost the exact notation we just saw. So let’s look at some examples.

{
    "firstName": "Sander",
    "lastName": "Rossel"
}

{
    "innerObj": {
        "someValue": null
    },
    "anotherInnerObj": {
        "innerInnerObj": {}
    },
    "message": "Phew, what syntax!"
}

That’s looking pretty familiar now, doesn’t it? And, if you compare it to XML, it’s a lot more compact, saving you precious bits and bytes when you’re sending your data over the internet!

Making an AJAX request

So let’s look at an AJAX example. I’ll start very simple making a synchronous request that returns just plain text (so no XML or JSON) when the page loads. You’ll know that the request doesn’t refresh the page because if it would the page would keep refreshing (as it makes the request upon loading). Alternatively, you can track all requests your browser makes using your browsers developer tools (press F12 in IE, FireFox or Chrome and navigate to the Network tab). I’m using jQuery to get the page load event and to show the result of our AJAX request. So here’s the HTML (in a file called Ajax.html):

<!DOCTYPE html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script type="text/javascript" src="Ajax.js"></script>
    </head>
    <body>
        <p id="result"></p>
    </body>
</html>

Here’s our JavaScript (Ajax.js):

$(function () {
    var ajax = new XMLHttpRequest();
    ajax.open('GET', 'Ajax.php', false);
    ajax.send();
 
    $('#result').text(ajax.responseText);
});

And finally our PHP (Ajax.php):

<?php
    echo 'Result of AJAX request!';
?>

So all of these files go into the htdocs folder of your XAMPP installation and you’ll have to access your page by browsing to localhost/Ajax.html (notice I named all files ‘Ajax’). So what’s really interesting here is that in my JavaScript I’m using an XMLHttpRequest object. So we call the open method and pass in a string specifying the HTTP method, GET or POST. Next we’re telling it what URL to navigate to and last we’re specifying whether the request should be asynchronous (we’re calling it synchronous). Then we send the request to the server. So, because we’re calling it synchronous the browser blocks until we get response from the server. That means that on our next line of code we simply have our result, ajax.responseText. Now you’ll never do this, in fact, our browser even gives off a warning saying that this method is deprecated because it negatively affects the user experience. In our case we won’t notice the blocking, but if we’re downloading larger chunks of data our page will freeze up completely!

So let’s make that call asynchronous so the user can go about doing his business while our page gets our data for us. This isn’t actually to hard. We simply change our JavaScript to the following:

$(function () {
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function () {
        if (ajax.readyState == 4) {
            $('#result').text(ajax.responseText);
        };
    };
    ajax.open('GET', 'Ajax.php', true);
    ajax.send();
});

So I’m specifying an onreadystatechange function which gets called when the state of our ajax object changes. State 4 means it’s done and we can get the result.

Now there are quite some options we can set and check, but I’ll not get into that. You can check them on the XMLHttpRequest documentation page and play around with them yourself. Instead, we’re going to use jQuery to make AJAX requests.

Using jQuery for AJAX requests

You might be thinking if there’s anything jQuery cannot do? There’s actually plenty of stuff you don’t want to do using jQuery, but AJAX isn’t one of them. jQuery makes AJAX pretty easy actually. We were already using jQuery, so we can simply edit our JavaScript.

$(function () {
    $.ajax({
        type: 'GET',
        url: 'Ajax.php',
        complete: function (jqXHR) {
            $('#result').text(jqXHR.responseText);
        }
    });
});

So remember I was telling you about using an object to specify options? This is one such an example. We’re passing in an object and specify the type, the url and a function that will be called when the requests completes (jqXHR stand for jQuery XMLHttpRequest, but you can name it anything). We could’ve passed in much more, but we didn’t. So this does the same as the code we had earlier.

The jQuery.ajax function can actually do a whole lot of stuff! Next we’re going to pass in some parameters and echo them on our page.

$(function () {
    $.ajax({
        type: 'GET',
        url: 'Ajax.php',
        data: {
            artist: 'Led Zeppelin',
            song: 'Immigrant Song'
        },
        complete: function (jqXHR) {
            $('#result').text(jqXHR.responseText);
        }
    });
});

And now we need to alter our PHP too.

<?php
    if (isset($_REQUEST['artist']) &&
        isset($_REQUEST['song']))
    {
        $artist = $_REQUEST['artist'];
        $song = $_REQUEST['song'];
        echo "The song '$song' by $artist rocks!";
    }
?>

So that was pretty easy, right? We just passed in a JavaScript object with some properties and they were converted to parameters in our PHP automatically! So how does this work the other way around? This is where JSON comes into play! JSON stands for JavaScript Object Notation, so it should be pretty easy for JavaScript to create actual objects that we can use. So let’s start by modifying our PHP so that it returns JSON.

<?php
    class song
    {
        public $artist = NULL;
        public $name = NULL;
    }
 
    if (isset($_REQUEST['artist']) &&
        isset($_REQUEST['song']))
    {
        $song = new song();
        $song->artist = $_REQUEST['artist'];
        $song->name = $_REQUEST['song'];
 
        header('Content-Type: application/json');
        echo json_encode($song);
    }
?>

First of all, I’m using an object to store our data. We’ve seen this before. I’m setting our response header so that it tells our browser it’s json. Then I’m using the json_encode function to convert our object into JSON. If you now check out the result in your browser you’ll notice that we’ve received some actual JSON!

But what we really want is to use this JSON in our JavaScript as if it were just an object. Actually this is pretty easy! We can get the object from the XMLHttpRequest.

complete: function (jqXHR) {
    var song = jqXHR.responseJSON;
    $('#result').text("The song '" + song.name + "' by " + song.artist + " rocks!");
}

And that’s it. Alternatively, we can use the ‘success’ option, a function that passes us the returned data, the status of the request and the XMLHttpRequest.

$(function () {
    $.ajax({
        type: 'GET',
        url: 'Ajax.php',
        data: {
            artist: 'Led Zeppelin',
            song: 'Immigrant Song'
        },
        success: function (song, status, jqXHR) {
            $('#result').text("The song '" + song.name + "' by " + song.artist + " rocks!");
        }
    });
});

And likewise there is an ‘error’ option.

$(function () {
    $.ajax({
        type: 'GET',
        url: 'Ajaj.php',
        data: {
            artist: 'Led Zeppelin',
            song: 'Immigrant Song'
        },
        success: function (song, status, jqXHR) {
            $('#result').text("The song '" + song.name + "' by " + song.artist + " rocks!");
        },
        error: function (jqXHR, status, errorThrown) {
            $('#result').text('An error occurred: ' + jqXHR.status + ' ' + errorThrown);
        }
    });
});

Notice that I’m calling ‘Ajaj.php’, a page that doesn’t exist. Naturally we’ll get 404, Not found. When using the ‘complete’ option we used earlier you’d have to check for success yourself, our current implementation would actually break our page if we called ‘ajaj.php’.

So there’s actually quite a bit to think about when using AJAX. Did the server return a result, what kind of result did it return, was the request successful, etc. We can use the XMLHttpRequest object for this. Check ‘status’ to see if our request was successful (status 200 means success) and then ‘responseType’ and any of ‘response’, ‘responseText’, ‘responseJSON’ or ‘responseXML’ for the result.

Posting data

So in the previous examples we’ve taken a look at the GET method. In the next example I’m going to take our movies page we created in my previous blog posts, Web development #4: PHP in the back and Web development #5: User input with HTML Forms. So first of all we’ll have to edit the PHP file. We want the form to go, because that refreshes the page. We also want to add jQuery and a custom JavaScript file to our header. Last, we need to give some ids to some elements because now we need to update the page ourselves once we add a new movie (after all, the page isn’t refreshing). So without further delay, here’s the modified PHP.

<?php
    if (isset($_POST['movieName']))
    {
        $movieName = $_POST['movieName'];
        if ($movieName)
        {
            file_put_contents('movies.txt', htmlspecialchars($movieName) . "rn", FILE_APPEND);
        }
 
        exit();
    }
?>
<!DOCTYPE html>
<html>
    <?php
        function fileAsUnorderedList($fileName, $notFoundMessage)
        {
            if (file_exists($fileName))
            {
                echo '<ul id="movies">';
                $lines = file($fileName);
                foreach ($lines as $line)
                {
                    echo '<li>' . htmlspecialchars($line) . '</li>';
                }
                echo '</ul>';
            }
            else
            {
                echo $notFoundMessage;
            }
        }
    ?>
    <header>
        <title>My favourite movies!</title>
        <meta charset="utf-8">
        <meta name="description" content="A list of my favourite movies.">
        <meta name="keywords" content="Favourite,movies">
        <meta name="author" content="Sander Rossel">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script type="text/javascript" src="Movies.js"></script>
    </header>
    <body>
        <h1>My favourite movies!</h1>
        <p>
        <?php
            fileAsUnorderedList('movies.txt', 'No favourite movies found!');
        ?>
        </p>
        <h2>Add a movie!</h2>
        <div>
            <label for="movieName">Movie name</label>
            <input type="text" name="movieName" id="movieName" />
            <button id="submit">Submit</button>
        </div>
    </body>
</html>

And then we need to add a JavaScript file (I’ve called it Movies.js) to add an event handler to our button click event which takes the value of the input, posts it to the server and on success adds the movie to our list and empties the movie input.

$(function () {
    $('#submit').on('click', function () {
        var movieInput = $('#movieName');
        var movieName = movieInput.val();
        if (movieName) {
            $.ajax({
                type: 'POST',
                url: 'Movies.php',
                data: {
                    movieName: movieName
                },
                success: function (data, status, jqXHR) {
                    $('#movies').append('<li>' + movieName + '</li>');
                    movieInput.val(null);
                },
                error: function (jqXHR, status, errorThrown) {
                    alert("An error occurred while adding movie '" + movieName + "'.");
                }
            });
        };
    });
});

And there you have it. Looks complicated? I guess it is a bit, but once you get the hang of it it’s not so bad. And luckily the documentation is rather good!
Another cool addition to our page would be pagination. Let’s say we are going to add hundreds of movies. Getting those all in once might slow down our page quite a bit. So we can use AJAX to get just ten, or twenty, or fifty at a time. The page could load them on a button click or when we scroll to the end of the page (that is, get the movie titles and add them to our list using jQuery, also make sure you ‘remember’ what page you’re on). This principle is called pagination and can greatly enhance user performance (and for large websites it’s even a must).

So that’s it for AJAX. And actually, that’s it for web development! You’ve now seen everything involved in creating awesome, responsive web pages. Of course there’s still a long way to go as we’ve only scratched the surface of web development. We’ve seen the tools, but are by no means expert in any of them. In my next, and last, blog post I’ll give you some tips on frameworks and libraries that can help you create the pages you want.

Stay tuned!