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.

227 lines
6.8 KiB

# 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
<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
```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
<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
```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
<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
```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)