Service in AngularJS and services that communicate with the server
- 24-07-2022
- Toanngo92
- 0 Comments
The concept of Service in AngularJS are functions to perform certain tasks, personalize entities, code easy to maintain and test, services play a very important role in applications written in AngularJS. , there are already available services that Angular has provided for us, but we can completely extend it by creating a new Service. Here is a list of some of the Services builtin in AngularJS:
$anchorScroll $animate $cacheFactory $compile $controller $document $exceptionHandler $filter $http $httpBackend $interpolate $interval $locale $location $log $parse $q $rootElement $rootScope $sce $sceDelegate $templateCache $templateRequest $timeout $window $event
Mục lục
Introduce some popular services or use
$scope and $rootscope
See more at the article scope in AngularJS
$window
Similar to the window object in pure javascript.
$event
Similar to the event object in pure javascript, used to catch events
$location
Represents current browser's url similar to location object in pure javascript
$http
To use this $http service, we need to understand REST API architecture, you can see more in the article Services communicate and REST API concept to get more knowledge before starting.
Docs: https://docs.angularjs.org/api/ng/service/$http
$http in angularJS is a service (business) in angularJS to communicate with the server through .get(), .post() methods to get data or send data through Ajax(), return message data as JSON, this mechanism is asynchronous mechanism , javascript sends a request to the server side, the source code continues to run without waiting for a response, when the server sends data back to the browser, it catches the return data and continues. Executes the code that the programmer has defined to work with the returned data such as parsing data, updating HTML, etc. Basic REST API methods like GET,POST,PUT,DELETE are defined. available in the $http service.
Syntax:
$http({ method: 'GET', url: '/endpoint', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer APIKEY' } // optional }) .then( function (success) { // do something when success }, function (error) { // do something when error } );
In addition, we also have shortcuts for 2 methods, making the syntax more concise, we can choose the method that is right for us to apply.
app.run(function($http) { $http.defaults.headers.common['Authorization'] = 'Basic APIKEY'; }); // optinal config header $http.get('/someUrl', config).then(successCallback, errorCallback); $http.post('/someUrl', data, config).then(successCallback, errorCallback);
$http service is a function, takes 1 parameter, this parameter is the configuration object (object) for the request, this object defines the state for the HTTP method, the url path, configures the header for the method if yes, or can configure body if method is POST…
The object when an http request is sent or returned has the following structure:
- data : is the data returned from the server side according to a standard, can be string, or text
- status : HTTP status code
- headers : refer to header information
- config : reference to an http request configuration object
When an HTTP method is called, the object returned is called a promise object. This object contains the standard method .then(), meaning that after the successful return signal. , do something, and catch the situation when dealing with success or error, the parameters in the then() function are 2 callback functions with the parameter being a success variable, which will store the object when the request is successful, The error variable stores the object when the request encountered an error. The meaning can be understood that if successful, will do something with the data returned in the success variable, similar to the error variable when an error is encountered.
Here is an example that uses the get() method of the $http service to communicate with the server
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Exmample Http method</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script> </head> <body> <div ng-app="myApp"> <div ng-controller="listUserController"> <table> <tr> <th>Username</th> <th>Name</th> <th>Email</th> </tr> <tr ng-repeat="user in users"> <td>{{user.fields.username}}</td> <td>{{user.fields.fullname}}</td> <td>{{user.fields.phonenumber}}</td> </tr> </table> </div> </div> </body> <script> var app = angular.module('myApp', []); // app.run(function($http) { // $http.defaults.headers.common['Authorization'] = 'Basic keyMhcG4dscdHl3Nf'; // }); app.controller('listUserController', function ($scope, $http) { $scope.listUser = []; $scope.getListUser = $http({ url: "https://urlservcer", method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer APIKEY' } }).then( function (data) { $scope.users = data.data.records; }, function (error) { console.log(error); alert("get list Failed"); }); // $scope.getListUser(); }); </script> </html>
Considering the example above, I'm sending a get method to the server through the $http service, the data after being retrieved is returned through the .then() method, this method has 2 parameters passed in: another function, the first parameter is the callback function when sending the request successfully (200), the second parameter is the function called when the request reports an error.
Further development, we can implement CRUD features that display a list of users, add new users on the server side by combining get and post methods
$resources
Docs: https://docs.angularjs.org/api/ngResource/service/$resource
$resource service in angularJS allows us to access REST applications, similar to $http but the data standard needs to meet the JSON standard, comply with the correct structure, meaning that $resource receives data from the endpoint , the data has its own normalization that interacts with the data and then sends it back, which is quite useful for developing CRUD applications. In comparison, $http will interact with the server more diverse than $resource, but with $resource, if the server layer data is normalized, the operation will be faster.
$resource . application example
Step 1: create index.html file in resource folder
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Example resourece</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script> <!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.js"></script> --> <script src="https://code.angularjs.org/1.2.32/angular-resource.js"></script> </head> <body> <div ng-app="myApp"> <div ng-controller="listUserController"> <table> <tr> <th>Username</th> <th>Name</th> <th>Email</th> </tr> <tr ng-repeat="user in users"> <td>{{user.fields.username}}</td> <td>{{user.fields.fullname}}</td> <td>{{user.fields.phonenumber}}</td> </tr> </table> </div> </div> </body> <script> var app = angular.module('myApp', ['ngResource']); // app.run(function($http) { // $http.defaults.headers.common['Authorization'] = 'Bearer keyMhcG4dscdHl3Nf'; // }); app.controller('listUserController', function ($scope, $resource) { $scope.users = []; $scope.getListUsers = $resource('http://localhost/resource/listuser.json').query(function(){ $scope.users = $scope.getListUsers; }); // console.log( $scope.getListUsers); }); </script> </html>
Step 2: create the file listuser.json at the same level as the index file with the json structure array of objects:
[ { "id": "recFrt8MNiEg4jInj", "createdTime": "2022-04-22T09:19:18.000Z", "fields": { "password": "1234567", "phonenumber": "0911222333", "username": "toan1234", "fullname": "username 3" } }, { "id": "recT2YNM75XbD4E4T", "createdTime": "2022-04-27T13:15:49.000Z", "fields": { "phonenumber": "0932159215", "username": "to9an1134", "fullname": "Toan ngo vinh" } }, { "id": "recaE9soCIeZgyhVP", "createdTime": "2022-04-22T09:19:18.000Z", "fields": { "password": "1234567", "phonenumber": "0932321592", "username": "toanngo92", "fullname": "toan ngo" } }, { "id": "rectJwBmOAsWDWHnw", "createdTime": "2022-04-28T01:03:47.000Z", "fields": { "phonenumber": "0932159215", "username": "to9an1134", "fullname": "Toan ngo vinh" } }, { "id": "recvDBMvANFv5UiK8", "createdTime": "2022-04-22T09:19:18.000Z", "fields": { "password": "1234567", "phonenumber": "0782222567", "username": "toan123", "fullname": "username 2" } } ]
Difference between $http and $resource when accessed via REST API
$http service processing mechanism through AJAX, and most programmers will use in cases, through this business, programmers will create GET,POST,DELETE … and handle the The returned object, however, is less commonly used in real projects, perhaps because of its complex structure, less sample code, and the return data is not a promise, so it is more difficult to access for newcomers.
In a RESTful scenario, $resource hugs $http, meaning that with a RESTful web service, $resource is the option to use. With $http, we can send requests to the server with other structures, for example, send a request to a website that does not follow the data structure of the API and receive the returned data as the entire html content returned from request. As for $resource, it follows the structure of RESTful.
Restangular
Docs:
One service that can access REST services is Restangular, which is a third-party library that is injected into the project through dependency injection . It simplifies HTTP Requests by reducing the amount of code to write, can be used to make interactive RESTful API applications replacing angularJS's default $http, of course the default methods are complete.
Strengths of Restangular:
- Supports all HTTP methods
- No need to rewrite the URL many times, just define the endpoint for resources once, the next time will follow the endpoint structure to communicate
- Allow custom method configuration
Example when implementing GET method with Restangular:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Exmample Http method</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.js"></script> <!-- bat buoc phai load lodash truoc khi load restangular --> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/restangular@1.6.1/src/restangular.js"></script> </head> <body> <div ng-app="myApp"> <div ng-controller="listUserController"> <table> <tr> <th>Username</th> <th>Name</th> <th>Email</th> </tr> <tr ng-repeat="user in users"> <td>{{user.fields.username}}</td> <td>{{user.fields.fullname}}</td> <td>{{user.fields.phonenumber}}</td> </tr> </table> </div> </div> </body> <script> var app = angular.module('myApp', ['restangular']); app.config(function (RestangularProvider) { RestangularProvider.setBaseUrl('https://api.airtable.com/v0/apppcdfKQ5q5rch7A'); RestangularProvider.setDefaultHeaders({ 'Content-Type': 'application/json', Authorization: 'Bearer APIKEY' }); }); app.controller('listUserController', function ($scope, Restangular) { $scope.users = []; $scope.getListUsers = Restangular.all('user').doGET().then(function (result) { $scope.users = result.records; console.log($scope.users); }); console.log($scope.getListUsers); }); </script> </html>
Error handling when communicating client-server
Error handling and exception logging are very important in communication, because in reality, there are many situations that occur, such as connection problems, server infrastructure failures, database failures, etc. .
We use try, catch, finally blocks to catch these exceptions. In angularJS, there is a way to save time because there is a $exceptionHandle service used to catch exceptions and not affect the application's route, because these errors are usually not related to the syntax
Example exception in angularJS:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Exmample Http method</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.js"></script> </head> <body> <div ng-app="myApp"> <div ng-controller="listUserController"> <table> <tr> <th>Username</th> <th>Name</th> <th>Email</th> </tr> <tr ng-repeat="user in users"> <td>{{user.fields.username}}</td> <td>{{user.fields.fullname}}</td> <td>{{user.fields.phonenumber}}</td> </tr> </table> </div> </div> </body> <script> var app = angular.module('myApp', []); app.config(function($provide){ $provide.decorator('$exceptionHandler',function($delegate){ return function (exception,cause){ console.log(exception,cause); $delegate($exception,cause); } }); }); app.controller('listUserController', function ($scope, $http) { $scope.users = []; $http({ url: "https://api.airtable.com/v0/apppcdfKQ5q5rch7A/user", method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer APIKEY' } }).then( function (data) { console.log(data); $scope.users = data.data.records; console.log($scope.users); }, function (error) { console.log(error); alert("get list Failed"); }); // $scope.getListUser(); }); </script> </html>