Welcome to a hands-on tutorial on writing reusable user interface components with AngularJS. In this tutorial, we’ll write a table control that asynchronously loads data from a server, display it, and allows the user to sort the data by clicking table headers. The sorting is done client-side. We’ll show how to write a REST-server in PHP, how to define custom HTML elements in AngularJS, and how to setup a controller for the elements. To top it off, we’ll write CSS for our table in such a way that it can be dropped into a user interface in a snap, and scales fluidly with the space allotted to it.
The first part of this tutorial introduces AngularJS, and takes you through the use of the Slim PHP Microframework and the Idiorm and Paris ORM libraries in order to write a RESTful web service, which we’ll need for our table control to talk to.
What is AngularJS?
- Extend the HTML vocabulary for your application. That is, add new HTML elements;
- Bind data to your user interface, automatically wiring up update events as necessary;
- Validate forms;
- Communicate with a server through AJAX;
- Perform localization.
What we’ll create
We’ll use AngularJS to create a new HTML tag,
<mytable>. This tag will allow us to declaratively insert an AJAX powered table. In other words, you simply add a
What we’ll get is something like this:
Our table will fill the screen space available to it, both horizontally and vertically. This means you can create a
<div> container somewhere on your page with a set width and height (or even a flexible with and height) and put the table in there – it will scale automatically. Incidentally, this has nothing to do with AngularJS but rather with writing crafty CSS, which is all part of the game.
It will be possible for the user to click the table column headers and sort the data in the table automatically.
While we’re exploring AngularJS, let’s take the opportunity to look at how our table will access data from a database. We’ll need to offer and endpoint for our table’s AJAX requests to connect to. Let’s do this nicely, and build a REST interface (more on this below). We’ll also use the Idiorm and Paris PHP libraries to write simple, readable and robust database access code.
Setting things up
Let’s get some requirements out of the way first. We’ll need a MySQL database for our table control to access, and some data in it. For this tutorial, we’ll use a database called wine, containing a single table called wine with the following schema:
You can create this database with MySQL Workbench, or directly in the MySQL console. Fill it with some data so that we’ll have something to test with.
Other AngularJS tutorials seem to use wine lists as well, so why not follow suit.
In order to talk to a database, you’ll need to have a back-end written in some flavor of server-side language. PHP’s a good candidate; so is Ruby. The back-end code runs on the (database) server, and cannot be seen or altered by your web app’s users.
So along these lines, you’d create other URLs like:
In other words, a CRUD interface: CReate, Update and Delete (and various getters). All of these URLs are accessed through GET or POST requests (this becomes interesting in the next paragraphs).
Moving to REST
So on to REST. REST stands for Representational State Transfer, and apparently there are many ways to explain what it is. Actually, it’s an academic concept and I’ve no desire to join any friendly flame war, so rather than mince words, we’ll just do.
Let’s put it like this: REST uses HTTP verbs to indicate actions to be performed against a database.
- When you send an HTTP GET request, a REST web service (a “restful” web service) will get some data from a database and return it.
- When you send an HTTP POST request, a REST web service will create a new record in a database.
- When you send an HTTP PUT request, a REST web service will update a record in a database.
- When you send an HTTP DELETE request, a REST web service will delete a record in a database.
You’re likely familiar with GET and POST requests; your browser can send PUT and DELETE requests as well although they’re much less used on the web.
So there it is – REST puts the semantics of HTTP requests to good use. Rather than have many URLs for your web service (like in the example above), you’ll have just one: wine. The HTTP verb used to access it determines what the web service will do to the database.
While we’re at it, it’s also customary to introduce URL rewriting at this point. Rather than accessing
using a GET request, it’s much prettier to be able to write:
URL rewriting (offered by both the IIS and Apache web servers) make this possible, without requiring changes to your code.
Writing a RESTful webservice
Let’s put the theory in practice. Before we can turn our attention to AngularJS, we’ll need a web service set up for database access, so let’s stick to REST for a while longer.
Writing the PHP code to access a MySQL (or any other) database is straightforward, but error prone without the use of various libraries that make your life easier. You could, technically, do this:
I’m going to beg you not to do this. There are less painful ways. Here’s some reasons to convince you.
mysql_xxxfunctions are deprecated.
- You’re better off using PDO functions, as they are safer and allow query parameterization.
- You don’t actually have to write the queries yourself, since you can use _object relational mapping.
The last point is the most important point. You don’t have the manually craft SQL queries anymore (unless you need some very particularly crafted queries). Object Relational Mapping (ORM) can work for you. C# and Java developers have been using it for years (the Hibernate library being a case in point), and there are mapping libraries for PHP, too.
Idiorm and Paris
Get the Idiorm and Paris libraries here. Take a moment to study that page; it illustrates the power of ORM in PHP nicely. Note that you just need the idiorm.php and paris.php files; the rest is fluff. Now let’s look at this code:
No queries. No stripslashes. No mess. We’re not actually using parameters here, but trust me, you don’t have to do anything arcane to use them.
Just to whet your appetite a bit more, here’s some more examples.
Getting wine #6 from the database (told you it was easy to insert a parameter!):
Creating a new wine:
If that doesn’t make you happy, I don’t know what will. So cast off your old ways and start using ORM. There’s more PHP ORM libraries out there, and you can always roll your own.
Using the Slim PHP microframework
With the ORM bit out of the way, it’s time to set about implementing the actual REST web service. We’ve put together enough tools do to this now, but we can still make life a little bit easier by using a framework to do the grunt work for us. Rather than writing PHP code that determines whether a request was a GET, POST, PUT or DELETE request, and fishing the request arguments from the HTTP header, we can use the Slim PHP microsframework to do this for us.
Get the Slim framework here.
Slim is a very small framework that allows you to specify routes for HTTP request, along the lines of “If this is a PUT request for a wine with ID x, then do this. If this is a GET request for a wine with ID y, then do this.”
Setting up Slim is easy:
Let’s define a route for retrieving a wine by ID.
This route is for URLs of the form
We use Slim to send out an HTTP header indicating that JSON content is forthcoming. Then we use Paris to grab wine #6 from the database, and send it back to the browser in JSON format – all that in surprisingly little code.
However, we’ll need to do a little more to make this robust.
This code adds two important things:
- Wine names can contain diacritics. In order for them not to be mangled when they get sent to the browser, we encode them as UTF8.
- If wine #6 cannot be found, our REST web service must return an error message, encoded in JSON.
Let’s write another route. This one is for /wines, which retrieves all wines:
Here’s a route for POSTing a new wine:
You can now write additional routes for PUT and DELETE – I’ll leave that as an exercise.
Great – it’s all come together. Using the Slim Microframework, along with the Idiorm and Paris ORM libraries, we’ve written a RESTful web service, which allows the following requests:
- GET http://www.myhost.com/webservice/wine (No ID – get all wines)
- GET http://www.myhost.com/webservice/wine (with an ID)
- POST http://www.myhost.com/webservice/wine (with name in POST data)
- PUT http://www.myhost.com/webservice/wine (with ID and name in HTTP data)
- DELETE http://www.myhost.com/webservice/wine (with ID in HTTP data)
Having done all this, we can now focus on the front-end of our web application, and actually look at AngularJS.