Sometimes we want to put HTML into our page after the page has rendered. Perhaps we need user input to create something, rather than show/hiding it. Perhaps we want to call a server to get data that matches the user's stipulations, and then display that data in HTML.
As you can see, that's not very readable or maintainable. These days we use a system called 'Client-side Templating' that abstracts all that difficulty away! There are lots of templating libraries out there, but we are going to use Handlebars...
A Quick Guide to using Handlebars
Include the Handlebars script in the page (CDN or local)
Insert templates into the page using script tags, like:
The {{<something>}}s are where we will insert data which is relevant to the piece of HTML we are creating.
The next step is to get hold of the template markup and use it. To do this we need to copy it, and then Handlebars needs to 'compile' it.
Compilation is when Handlebars takes the contents of that script block and turns it into a function that outputs html. The function accepts an argument (which is an object) that contains any extra data required to manufacture that particular piece of HTML.
Once stored, you can use a template repeatedly, say for rendering a list of products, by calling that function and passing the data for a different product each time. We refer to this data as the 'context' in which the template is rendered.
var source = $("#my-template").html(); //Gets template markup from inside the script tag
var template = Handlebars.compile(source); //Returns a function we'll use to create HTML chunks
Next you must get hold of the data that you'll use to render that particular piece of html. (The context) e.g.:
var data = {title: "New HTML", body: "This is my templated content!"};
You then call the template function we created above, passing the data. This will return the new HTML:
var html = template(data);
This produces the HTML:
<div class="entry">
<h3>New HTML</h3>
<div class="body">
<p>This is my templated content!</p>
</div>
</div>
Now insert it into the page:
$('#targetArea').html(html);
Exercise:
Build your own templates:
Just HTML
HTML from template with data
HTML from precompiled template with data
Inject them here:
AJAX
For this next section we'll require npm and the use of your command line.
To find your command line on mac:
Press CMD + space to bring up your spotlight program.
Type terminal into spotlight and at some point it will auto-suggest the terminal application.
Hit return or click on it to activate.
To find your command line on windows 10 (which sadly isn't as good):
press the start button
then type command prompt. At some point it will auto-suggest the terminal application.
Hit return or click on it to activate.
npm is node.js' package manager. If you type npm -v into your command line and hit return and get a message saying that npm is not recognised, then you'll need to install node.js from https://nodejs.org/en/download/
To use ajax reliably you need your page to be on a server: This can be a local server (i.e. one that is running on your machine) or a remote server. To create a quick and easy local server, I recommend httpster. Install it globally using npm: Type npm i -g httpster into your command line and hit return.
To start the server, navigate on the command line into the folder that this page is in and the simply type httpster and hit return. You will instructed to browse to something like http://localhost:3333: Do so.
What AJAX does
AJAX stands for Asynchronous Javascript and XML. The internet was first designed to move between static documents. You moved from page to page and any changes would be shown in the next page. In the late 1999 Microsoft added an ability for Internet Explorer to call out to a server for more information without refreshing the page. This is known as asynchronous.
AJAX allows us to call out to servers (including our own) for resources after the page has been loaded. We can call for actual html files (generally these are not whole pages and are known as 'partials') and insert them into our current page; specific data files (JSON or, less commonly, XML), or; we can call the server, using a non-specific URI and ask for a response (which is typically JSON)
Introducing JSON
JSON is a 'transport language'. It stands for 'JavaScript Object Notation'. It allows the transport of JavaScript objects between locations.
JSON can be formed of objects or arrays, and is formatted like a normal javascript, except that:
strings must use double quotes
keys must be in double quotes too
So this javasrcipt object:
{
name: 'james',
age: 38,
isTutor: true
}
becomes this JSON:
{
"name": "james",
"age": 38,
"isTutor": true
}
There is a global variable, JSON, available in your browser (window.JSON). The object is a helper object for dealing with JSON. If you type JSON into your console and hit return you'll be able to inspect it.
Objects or Arrays can be turned into JSON using JSON.stringify() and back again using JSON.parse(). On AJAX calls the response is usually converted for you on receipt of a response.
Making our first AJAX call
With natural javascript:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === XMLHttpRequest.DONE ) {
if (xmlhttp.status === 200) {
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
else if (xmlhttp.status === 404) {
alert('The resource was not found');
}
else {
alert('Error: Call to server failed with code: ' + xmlhttp.status);
}
}
};
xmlhttp.open("GET", "ajax_info.txt", true);
xmlhttp.send();
$.ajax({
method: 'GET', //optional. GET is the default if not provided
context: document.body, //optional. Scopes the response to a part of your page
url: '//api.github.com/users/jmsherry'
}).done(function(response){
console.log(response);
}).fail(function(error){ //just to show you how to error catch
console.error(error);
}).always(function(){ //this happens after EVERY ajax call
console.info("ajax call made");
});
You can obviously replace my username with yours, assuming you have a github account, to see what you get back.
Once you get a response, lets build a template and inset your details into the page:
var source = $("#profile-template").html();
var template = Handlebars.compile(source);
$.ajax({
url: '//api.github.com/users/jmsherry'
}).done(function(response){
//create HTML
var html = template(response);
//insert new HTML
$('#ajax-content').html(html);
});
Demo
Insert github profile here
Exercise:
Make your own ajax calls:
Make an HTML partial and call and inject into page
Make a .json file and call and template into page
Inject them here:
APIs
When you called GitHub you called a thing called an API (Application Program Interface). APIs are set up by people/organisations to allow others to interact with their business through servers
REST APIs
What is REST
REST stands for REspresentational State Transfer. REST is a way of keeping the state of an application in sync on the client and the server. For example, if a user removes an item from their shopping basket on the client we send an HTTP DELETE request to remove it from the basket on the server too.
HTTP verbs/methods used in REST
In development we have a thing called CRUD (Create, Read, Update & Delete). These are typical operations that you do with an app. REST has mapped those operations to HTTP methods so that everyone does things in a predictable manner, like so:
REST CRUD Relationship
Operation
HTTP VERB (Method)
Purpose
Create
POST
To send new data to the server.
Read
GET
To retrieve an item/list of items from the server
Update
PUT
To update the stored details of a record. e.g. Maybe the price of an item changed??
Delete
DELETE
To indicate removal or deletion of a thing. (Server handles how)
Typical URL Format of a REST API
The URL Structure is important in REST. Using the standard structure well documents the API for users (meaning that they can guess where to call to acheive their aims).
An API has places you can call to, called routes. An example route might be: http://tesco.com/groceries/fruit/apples. This makes it easy to guess where you'd call to get oranges, right?!
REST Routes
HTTP Verb/Method
Route
Purpose
GET
/posts
Get all the posts
GET
/posts/1
Get a post with an id of 1
GET
/posts/1/comments
Get the comments from a post with an id of 1
GET
/comments?postId=1
Filter comments by id to get those related to a post with the id of 1 (Same as above but from a different angle.)
GET
/posts?userId=1
Get all posts made by the user with the id of 1
POST
/posts
Add a new post to the database. The 'body' of this request would have an object in it, like: {userId: 4, createdAt: 234877892, content: "hello world!"}
PUT
/posts/1
Also has a body which the server would use to update the post with an id of 1
DELETE
/posts/1
Delete the post with an id of 1
Testing APIs with Postman
Sometimes, rather than doing it in your console, you'll want to test ajax calls using a client program, so that the information is easier to see and you can configure the call better. I tend to use Postman. We'll just have a brief look at that.
jsonplaceholder
One public 'dummy' API you can use to test is https://jsonplaceholder.typicode.com/. If you use Postman (or any ajax; or just your browser [in the case of GETs]) to make a request to it, then it will respond with data. Try making a get request to https://jsonplaceholder.typicode.com/photos, or making a PUT request to https://jsonplaceholder.typicode.com/users/1
Exercise:
Make calls to jsonplaceholder and template the responses.