# AngularJS - AJAX ## Lesson Objectives 1. Describe AJAX 1. Use the $http module to make an AJAX request 1. Use the response from an AJAX request to update the DOM 1. Alter express bodyParser to accept AJAX requests 1. 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 ```javascript 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
Click me
``` ## 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 ```javascript $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 ```javascript 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 ```javascript $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
{{base.foundMovieTitle}} Click me
``` ## 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 ```javascript 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
Click me
``` file: public/js/app.js ```javascript 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)