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