You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.8 KiB

AngularJS - AJAX

Lesson Objectives

  1. Describe AJAX
  2. Use the $http module to make an AJAX request
  3. Use the response from an AJAX request to update the DOM
  4. Alter express bodyParser to accept AJAX requests
  5. Use cURL to send JSON

Describe AJAX

  • AJAX stands for Asynchronous JavaScript and XML, but we mostly use JSON instead of XML now.
  • With AJAX, the browser uses JavaScript to make requests to servers and parse the responses after a page has loaded.
  • This means data can be retrieved and the web page updated without needing to reload the entire page each time an update needs to happen.
  • This makes the application feel smooth and fast and much more like a native app, as opposed to a series of web pages that a user visits

Use the $http module to make a request

  • $http is a service which needs to get passed into the controller.
  • Inside the controller constructor function, $http is a function that makes a request to a server.
  • It takes an object as a parameter. This object can have many parameters which affect the request.
  • $http returns a "promise" object.
    • On this object is a then property, which is a function.
    • You pass success and fail callbacks into this then function as parameters
    • These callbacks will be executed depending on what kind of response is received from the server

file: js/app.js

const app = angular.module('myApp', []);

app.controller('baseCtrl', ['$http', function($http){
  this.find = function(){ //this function will get called somewhere in the DOM
    $http({ //once it's called, make an AJAX call to OMDB
      method: 'GET',
      url: 'http://www.omdbapi.com/?t=star+wars&y=&plot=short&r=json&apikey=bea723f3'
    }).then(
      function(response) {
        //success callback
        console.log(response);
      },
      function(response) {
        //failure callback
        console.log(response);
      }
    );
  }
}]);

we can now call the find function

file: index.html

<html>
  <head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
    <script src="js/app.js"></script>
  </head>
  <body ng-app="MyApp">
    <div ng-controller="baseCtrl as base">
      <a ng-click="base.find()">Click me</a>
    </div>
  </body>
</html>

Use the response from an AJAX request to update the DOM

  • Inside the callback function for the AJAX request, the this keyword has been changed to browser window object

file: js/app.js

    $http({ //once it's called, make an AJAX call to OMDB
      method: 'GET',
      url: 'http://www.omdbapi.com/?t=star+wars&y=&plot=short&r=json&apikey=bea723f3'
    }).then(
      function(response) {
        //success callback
        console.log(response);
        console.log(this); //this no long refers to the controller, instead it's the window object
      },
      function(response) {
        //failure callback
        console.log(response);
      }
    );
  • To get around this, save this in a variable before you make the call

file: js/app.js

  this.find = function(){ //this function will get called somewhere in the DOM
    const controller = this;
    $http({ //once it's called, make an AJAX call to OMDB
      method: 'GET',
      url: 'http://www.omdbapi.com/?t=star+wars&y=&plot=short&r=json&apikey=bea723f3'
    }).then(
      function(response) {
        //success callback
        console.log(response);
        console.log(this); //this no long refers to the controller, instead it's the window object
        console.log(controller); //this references the controller
      },
      function(response) {
        //failure callback
        console.log(response);
      }
    );
  }
  • We can now update properties on the controller

file: js/app.js

    $http({ //once it's called, make an AJAX call to OMDB
      method: 'GET',
      url: 'http://www.omdbapi.com/?t=star+wars&y=&plot=short&r=json&apikey=bea723f3'
    }).then(
      function(response) {
        //success callback
        controller.foundMovieTitle = response.data.Title; //set a property on the controller equal to the movie title found in the AJAX response
      },
      function(response) {
        //failure callback
        console.log(response);
      }
    );
  • Lastly, we can print that controller property in the DOM

file: index.html

<html>
  <head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
    <script src="js/app.js"></script>
  </head>
  <body ng-app="MyApp">
    <div ng-controller="baseCtrl as base">
      {{base.foundMovieTitle}}
      <a ng-click="base.find()">Click me</a>
    </div>
  </body>
</html>

Alter express bodyParser to accept AJAX requests

We are now sending data via JSON, not through forms. We need to update bodyParser

file: server.js

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

app.use(express.static('public'));//static directory for js files

//change bodyParser.urlencoded({extended:false}) to bodyParser.json()
app.use(bodyParser.json());

//receive POST data
app.post('/', function(req, res){
  res.json(req.body); //res.json sends data back to the client in JSON format, which is easy for angular to parse
});

app.listen(3000, function(){
  console.log('listening');
});

We can send data to the server like so:

file: public/index.html

<html>
  <head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
    <script src="js/app.js"></script>
  </head>
  <body ng-app="MyApp">
    <div ng-controller="baseCtrl as base"><!-- controller -->
      <a ng-click="base.create()">Click me</a><!-- call find function -->
    </div>
  </body>
</html>

file: public/js/app.js

const app = angular.module('myApp', []);

app.controller('baseCtrl', ['$http', function($http){
  this.create = function(){ //this function will get called somewhere in the DOM
    $http({ //once it's called, make an AJAX call to OMDB
      method: 'POST',
      url: '/',
      data: { someProperty: 'somevalue' }
    }).then(
      function(response) {
        //success callback
        console.log(response);
      },
      function(response) {
        //failure callback
        console.log(response);
      }
    );
  }
}]);

Use cURL to send JSON

  1. Syntax for testing Express with cURL is different, since you're not sending form data, but JSON
curl -X POST -H "Content-Type: application/json" -d '{"username":"matt","password":"matty"}' http://localhost:3000/
  1. -H "Content-Type: application/json"
  • add a header saying that the type of file is JSON
  1. -d '{"username":"matt","password":"matty"}'
  • data must be formatted as JSON
  • property names and values must be in DOUBLE quotes (not single)