AngularJS Study Notes - Chapter 2: Communicating with Backend Servers

AngularJS is able to communicate with various backends via XMLHttpRequest (XHR) and JSONP requests, has a generic $http service for XHR and JSONP calls, and a $resource service specifically for Restful backend interfaces

 

In this chapter, we will examine the APIs and techniques for communicating with the backend, in particular the following:

  • Basic XHR calls using $http service, tested accordingly
  • Use the promise API provided by the $q service to make efficient asynchronous requests
  • Easily communicate with RESTful backends using the $resource factory
  • Build custom $resource-like APIs based on backend requirements

$http API Quick Tour

 

- -
GET $http.get(url, config)
POST $http.post(url, data, config)
PUT $http.put(url, data, config)
DELETE $http.delete(url, config)
HEAD

$http.head

  • url: call target URL
  • data: the data sent in the request body
  • config: Contains additional configuration information that affects both requests and responses

Handling HTTP responses: The request may succeed or fail. AngularJS provides two methods to register callbacks corresponding to these two results: success (success is called in the range of 200~299, and error is entered in the rest of the status) and error.

 

We can register success and failure callbacks on the object returned by calling the $http method

  • data: actual response data
  • status: HTTP status of the response
  • headers: function to access HTTP response header information
  • config: The configuration object provided when the request is fired

Configuration Object Description

  • method: HTTP method used
  • url: the target URL of the request
  • params: URL parameters
  • headers: additional request headers
  • timeout: Timeout (in milliseconds) before the XHR request is terminated
  • cache: cache switch for XHR GET requests
  • transformRequest\transferResponse: The data transformation function that processes the data before or after the backend exchanges data

 

var base_url = 'http://localhost:8080/'
angular.module('myapp1', [])
    .controller('myController', function($scope, $http) {
        var query = $http.get(base_url + "get");
        query.success(function(data, status, headers, config) {
            console.log(data);
            $scope.response = data;
        });
        query.error(function(data, status, headers, config){
            console.log('fail');
            console.log(data);
        });

        var cars = {
            toyota: {
                from: 'japan',
                price: 100000
            },

            benz: {
                from: 'Germany',
                price: 500000
            }
        }
        //The data of post and put accepts any Javascript object (or string), if it is an object, it is converted to a JSON string by default
        var post = $http.post(base_url + '/post/car', cars);
        // The $http service will perform a conversion from a JSON string to a Javascript object for any response that looks like JSON (with {}, [])
        post.success(function(data, status, headers, config) {
            console.log(data);
        });

    });

 In order to test a simple restful, you can use sts to create a simple springboot project, write a few get, and the post API is as follows:

 

 

public class HelloController {

    @RequestMapping("/hello/{name}")
    public String hello(@PathVariable("name") String name, Model model) {
        model.addAttribute("name", name);
        return "hello";
    }

    @RequestMapping("/get")

    public @ResponseBody String hello(HttpServletResponse response) {
    //In order to solve the problem of cross domain, you don't need allow *, your index.html is not deployed on the server at localhost:8080 where springboot is located
        response.addHeader("Access-Control-Allow-Origin", "*");
        return "{\"firstName\": \"John\", \"lastName\": \"Smith\", \"age\": 25}";
    }

    @RequestMapping(value="/post/car", method=RequestMethod.POST)
    public void post1(@RequestBody String body, HttpServletResponse response){
        System.out.println(body);
        response.addHeader("Access-Control-Allow-Origin", "*");
    }
}

 Promise API 

 

The main idea of ​​the promise API is to bring to the asynchronous world those conveniences we enjoy in the world of synchronous programming, such as chaining method calls and error handling.

 

In the Promise API, there are usually two roles: one is a placeholder (promise) that controls the execution of future tasks (delayed calls), and the other is a placeholder (promise) that depends on the execution results of future tasks (guaranteed promise results, resovle, reject)

 

AngularJS has a very lightweight Promise API implementation – $q service, AngularJS services with a large number of digits (mainly $http, $timeout, etc.) are quite dependent on the promise API style, so in order to run these services effectively, you need to be familiar with $q. 
/ /The introduction of $q is omitted here. The landlord has not understood it for the time being, and thinks it is not very useful. I will make up for it after I learn it.

 

The relationship between the Promise API and http, the promise object returned by http is then, which allows us to override the callback registration as follows

 

      var query = $http.get(base_url + "get");
      query.then(function(data, status, headers, config) {
              console.log(data);
              $scope.response = data;
          },
          function(data, status, headers, config) {
              console.log('fail');
              console.log(data);
          }
      )

RESTful endpoint farms provide CRUD operations, and while the code for such endpoint interactions is usually straightforward, it can be tedious to write. The $resource service allows us to eliminate duplicate code and let us operate at a higher level of abstraction, thinking about data manipulation in terms of resources, and replacing low-level HTTP calls with method calls.

 

 

The $resource service is distributed in a separate file (angular-resource.js) belonging to a dedicated module (ngResource). In order to utilize the $resource service, we need to include the angular-resource.js file and declare a module dependency on ngResource in the application module.

 

//HTML
    <div ng-controller="myController">
        <ul  >
            <li ng-repeat='user in users'>Name : {{user.name}}</li>
        </ul>
    </div>

//JS
     var base_url = 'http://localhost:8080/'
     angular.module('myapp1', ['ngResource'])
        .factory('Users', function($resource) {
            return $resource(base_url + 'get');
        })
        .controller('myController', function($scope, Users) {
            $scope.users = Users.query();
        })

 resourceAPI via

 

resource() method to use the $resources service. This method accepts three parameters.

  1. url (required) 
    Here we pass in a parameterized URL string template that contains all parameters and is used to locate resources (parameters are prefixed with ":")

 

//It should be noted here that if the parameter before : is empty (:id), then this part of the URL will be compressed into a . symbol.
//If the server we use requires the port number to be entered in the URL, for example: http://localhost:8080/:id then : must be escaped
//http://localhost\:8080/:id
$resource('/api/users/:id.:format',{
    format:'json',
    id: '123'
});

 

 

  1. paramDefaults (optional) 
    The second parameter contains the default value of the URL parameter when sending the request. The keys in the object are matched against the parameter names. If we pass in a parameter that is not set in the URL, it will be sent as a normal query string.
For example, if the URL string has a signature like /api/users/:id, and we set the default to {id:'123', name:'Ari'}, then the URL ends up being translated to /api/users/ 123?name=Ari
Here a value can be hardcoded as above, or it can be set to read dynamic values ​​from a data object. If you want to set it dynamically, you need to prefix the value with the @ character
{id:’@_id.$oid’}

 

  1. actions (optional) 
    The action object is a hash object with custom actions that can extend the default resource actions. 
    The key of the object is the name of the custom action, and the value of the object set by $http will replace the corresponding parameter in the URL.
$resource('/api/users/:id.:format', {
    format: 'json',
    id: '123'
}, {
    update: { methos: 'PUT' }
});
//action: {method:?, params:?, isArray:?, headers:?}
//isArray indicates whether the response returns [] or {}

 $resource creates async method

$scope.users = Users.query();
console.log($scope.users.length); //This will not get the length of the array you expect, but will return 0
// So you have to use async methods to do it.
Users.query(function(users){
    $scope.users = users;
    console.log(users.length);
})

 

The $resource service automatically generates two sets of methods. One set of methods will be at the class level, and the other set of methods will be at the instance level

 

 class level

- Users.query(params, successcb, errorcb) : GET request expects JSON data to return, used to get a list of items
- Users.get(params, successcb, errorcb): GET request, expect JSON to return a single object, used to get a single entry
- Users.save(params,payloadData, successcb, errorcb): POST request, please generate in the payload
- Users.delete(params, successcb, errrorcb):DELETE请求。

 params gives us parameters for each action, which will be part of the URL, or as parameters in the query string.

 

instance level

var user = new Users({
    name : 'SuperHero'
});

user.$save();
user.$delete();

 

 custom method 

The default methods generated by the $resource factory are quite sufficient for typical use cases, but it is also fairly easy to add custom methods at the resource level if some operations on the backend use a different HTTP verb (such as PUT or PATCH).

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326711686&siteId=291194637
Recommended