AJAX

Using AJAX in Node.js

XHR, jQuery, Fetch and Axios are not distributed with Node; you have to install it separately using npm. That said, Node comes with the http module which is the normal tool for choice for making HTTP requests from Node.

About AJAX

  • Stands for "Asychoronous JavaScript And XML"
  • AJAX is an approach on the client side to get/post request
  • Using HTML, CSS, JavaScript, DOM, XMLHTTP requests
  • AJAX is NOT a libray, framework nor a technology
  • Without AJAX, you have to refresh page to get to the next page e.g. reddit. With AJAX the page updated dynamically as you scroll down the page
  • With AJAX, websites can send and request data from a server in the background without disturbing the current page, which leads to today's single page app
  • With AJAX, server send back data in XML or Json (JavaScript Object Notation) format
  • Making Requests with JavaScript:
    • XMLHTTP Request (XHR)
    • Fetch API
    • 3rd Party Libraries: jQuery & Axios
      • curl

XMLHTTP Request (XHR)

  • Needs to parse returned data to JSON format: JSON.parse()
  • PROBLEMS WITH XHR:
    • Ugly, Bulky Syntax
    • It's 16 Years Old
    • No Streaming

Example: XMLHTTP: Get Request

var XHR = new XMLHttpRequest(); // create object
XHR.onreadystatechange = function() {
  if (XHR.readyState == 4 && XHR.status == 200) { //if request is done (4) & server is OK (200)
    console.log(XHR.responseText);
  }
};
XHR.open("GET", "https://api.github.com/zen");
XHR.send();

Example: XMLHTTP: Post Requests

var XHR = new XMLHttpRequest();
XHR.onreadystatechange = function() {
  if (XHR.readyState == 4 && XHR.status == 200) {
    console.log("it worked!");
  }
};

var url = "www.blah.com";
XHR.open("POST", url);
XHR.send("some data");

Exercise: XMLHTTP - Get Bitcoin Price

let url = "https://api.coindesk.com/v1/bpi/currentprice.json";
let btn = document.querySelector(".btn");
let priceDisplay = document.querySelector("#price");

window.onload = getPrice();

btn.addEventListener("click", () => {
  getPrice();
});

function getPrice(){
    let XHR = new XMLHttpRequest();
    let ccy = document.getElementById("ccy");
    let currency = ccy.options[ccy.selectedIndex].text;

    XHR.onreadystatechange = () => {

    if (XHR.status == 200 && XHR.readyState == 4){
        // remember to parse strings
      let price = JSON.parse(XHR.responseText).bpi[currency].rate; //bracket notation for variable (string)
      priceDisplay.innerText = `${currency} ${price}`; // remember .innerText
    }
    }
    XHR.open("GET", url);
  XHR.send();
}

Fetch

  • Return a Promise, can use .then & .catch to chain afterwards
  • Faster than XHR
  • Needs to parse returned data to JSON format:: data.json()
  • Not supported by IE

Example: Fetch

fetch(url) // return a Promise
.then(function(res) {
  console.log(res);
})
.catch(function(error) {
  console.log(error);
});

Example: Fetch Parsing with JSON

fetch(url).then(function(res) {
  return res.json();
}).then(function(data) {
  console.log(data);
}).catch(function() {
  console.log("problem!");
});

Example: Options (as Object)

fetch(url, {
  method: 'POST', // default method: GET
  body: JSON.stringify({ // turn JSON format into strings
    name: 'blue',
    login: 'bluecat',
  })
})
.then(function (data) {
  //do something
})
.catch(function (error) {
  //handle error
})

Example: Fetch Error Handling

fetch(url)
.then(function(res) {
        // This block handles the problem with the response itself
    if (!res.ok) {
        throw Error(res.status); // throw to .catch and skip .then
    }
    return res; // return to .then and continue
}).then(function(response) {
    console.log("ok");
}).catch(function(error) { // only cater problem with the Promise itself e.g. no internet
    console.log(error);
});

Template: Fetch: Error Handling Refactor

// with the following layout:
fetch(url)
.then(handleErrors)
.then(parseJSON)
.then(updateProfile)
.catch(printError);

Example: Fetch: Exercise- Random User Generator

let url = "https://randomuser.me/api/";
let btn = document.querySelector("#btn");

btn.addEventListener("click", () => {
    fetch(url)
    .then(handleErrors)
    .then(parseJSON)
    .then(updateProfile)
    .catch(printError);
});

function handleErrors(res){
    if (!res.ok) {
        throw Error(res.status);
    }
    return res;
}

function parseJSON(res){
    return res.json().then(function(data){ // convert string into json format
        return data.results[0]; //include common level in return, write shorter code in destructuring
    });
}

function updateProfile(parseData){
    let img = document.querySelector("#avatar");
    let fullName = document.querySelector("#fullname");
    let userName = document.querySelector("#username");
    let email = document.querySelector("#email");
    let city = document.querySelector("#city");

    img.src = `${parseData.picture.medium}`
    fullName.innerText = `${parseData.name.first} ${parseData.name.last}`; //Capitalize done in .css
    userName.innerText = `${parseData.login.username}`;
    email.innerText = `${parseData.email}`;
    city.innerText = `${parseData.location.city}`; //Capitalize done in .css
}

function printError(error){
    console.log(`problem! ${error}`);
}

jQuery

  • Combine making a get request and parsing json in a single function \$.ajax
  • Unlike XHR and fetch, don't have to parse the returned data. It's already in JSON format
  • jQuery AJAX methods
    • \$.ajax
    • \$.get
    • \$.post
    • \$.getJSON
    • the last 3 methods are shorthand methods of $.ajax
  • \$.ajax
    • The "base" jQuery method on AJAX

Example: Make a Request and Parsing JSON

$.getJSON('/my/url', function(data) {

});

Example: $.ajax: Creates an XHR GET request under the hood

$.ajax({
  method: "GET", // send request
  url: "some.api.com",
})
.done(function(res) { // success
  console.log(res);
})
.fail(function(){   // failed
  //do something
})

Example: $.ajax: GET request and manipulating the DOM

$("#btn").click(function(){
  $.ajax({
    method: "GET",
    url: "https://baconipsum.com/api/?type=meat-and-filler",
    dataType: 'json'    // optional: default is json
  })
  .done(addP)               // DOM manipulation
  .fail(function(){
    alert("OH NO! FAILED!");
  })
});

function addP (data){
  $("p").text(data[0]);
}

Example: $.get ($.ajax shortcut methods)

$("#getBtn").click(function(){
  $.get('https://api.github.com/users/colt')
  .done(function(data){
    console.log(data);
  })
  .fail(function(){
    console.log("ERROR!");
  })
});

Example: $.post ($.ajax shortcut methods)

$("#postBtn").click(function(){
 var data = {name: "Charlie", city: "Florence"};
 $.post("www.catsarecoolandsoaredogs.com", data)
  .done(function(data){
   console.log("HI!");
 })
  .fail(function(){
   console.log("ERROR!");
 })
});

Example: $.getJSON ($.ajax shortcut methods)

$("#getJSONBtn").click(function(){
  $.getJSON("https://api.github.com/users/colt")
  .done(function(data){
    console.log(data);
  })
  .fail(function(){
    console.log("PROBLEM!");
  })
});

Exercise: jQuery: Exercise- Random Cat Generator

$("#btn").click(function(){
  $.getJSON("https://random.cat/meow")
  .done(function(parseData){
    $("#photo").attr("src", parseData.file);
  })
  .fail(function(){
    console.log("Problem!");
  })
});

Axios

  • a light weight http request
  • can make http requests from node.js
  • automatically transform JSON data (same as jQuery, no Parse)
  • support by all browsers
  • CDN link available via github page
  • on error handling, axios allows you to distinguish the error is from the response or request

Example: Axios: Making Get Request Syntax

axios.get(url)
.then(function(res){
  console.log(res.data);
})
.catch(function(e){
  console.log(e);
})

Example: Axios: - Get Request

var url = 'https://opentdb.com/api.php?amount=1';
axios.get(url)
.then(function(res){
  console.log(res.data.results[0].question);
})
.catch(function(){
  console.log("ERR");
})

Example: Axios: - Error Handling

var btn = document.querySelector("button");
var section = document.querySelector("#comments");
btn.addEventListener("click", sendRequest);

function sendRequest(){
  axios.get("https://jsonplaaskjldceholder.typicode.com/comments", { // can pass object as parameter
    params: {
      postId: 1
    }
  })
  .then(addComments) // success
  .catch(handleErrors) // fail
 }

function addComments(res){
  res.data.forEach(function(comment){
    appendComment(comment);
  });
}

function appendComment (comment){
  var newP = document.createElement("p");
  newP.innerText = comment.email;
  section.appendChild(newP);
}

function handleErrors(err) { // allows you to distinguish the error is from the response or request
  if (err.response) {
    console.log("Problem With Response ", err.response.status);
  } else if (err.request) {
    console.log("Problem With Request!");
  } else {
    console.log('Error', err.message);
  }
}