More on Services

Before reading this article, first of all, please have a look at my previous articles (Part one and Part two) for better understanding.

In this article, I am going to explain more about one of the 8 main building blocks of Angular, that is, Services. In my previous article, I just explained what is it. Here, we will try to understand a little more with examples.

As I told you in my previous article, the created services need to be registered before we use them. To bring that statement with examples, please follow the below steps.

Step #1

First, I want to create a common proxy service class with HTTP verbs with unique signatures so that they can be used for all types of service requests throughout the application.

Below is the sample code snippet for the common proxy service class where we can define HTTP verbs with different signatures.

  1. import { Injectable } from '@angular/core';
  2. import { Headers, Http, RequestOptionsArgs, RequestMethod, Request, Response } from '@angular/http';
  3. import 'rxjs/add/operator/toPromise';
  4. import { Router } from '@angular/router';
  5. import { environment } from '../../../../environments/environment';
  6. import { SessionService } from '../SessionService/session.service';
  7. import {Logger} from 'angular2-logger/core';
  8. @Injectable()
  9. export class ProxyService {
  10. constructor(private http: Http, private router: Router, private _logger: Logger) {
  11. }
  12. /**
  13. * Perform GET request.
  14. *
  15. * @param uri Request or Relative URL specifying the destination of the request
  16. */
  17. get(uri: string | Request): Promise<any> {
  18. return this.request(this.newRequest(RequestMethod.Get, uri));
  19. }
  20. /**
  21. * Perform DELETE request.
  22. *
  23. * @param uri Request or Relative URL specifying the destination of the request
  24. */
  25. delete(uri: string | Request): Promise<any> {
  26. return this.request(this.newRequest(RequestMethod.Delete, uri));
  27. }
  28. /**
  29. * Perform POST request.
  30. *
  31. * @param uri Request or Relative URL specifying the destination of the request
  32. * @param body Request content
  33. */
  34. post(uri: string | Request, body: any): Promise<any> {
  35. return this.request(this.newRequest(RequestMethod.Post, uri, body));
  36. }
  37. /**
  38. * Perform PUT request.
  39. *
  40. * @param uri Request or Relative URL specifying the destination of the request
  41. * @param body Request content
  42. */
  43. put(uri: string | Request, body: any): Promise<any> {
  44. return this.request(this.newRequest(RequestMethod.Put, uri, body));
  45. }
  46. /**
  47. * Create a new http request for customization.
  48. *
  49. * @param method request type
  50. * @param uri to web service to prepended with configuration api endpoint
  51. * @param body request data
  52. * @returns {Request}
  53. */
  54. private blankRequest(method: RequestMethod, uri: string | Request, body?: any): Request {
  55. let req: Request;
  56. if (typeof uri === 'string') {
  57. req = new Request(<any>{
  58. method: method,
  59. url: uri,
  60. body: body
  61. });
  62. } else {
  63. req = <Request>uri;
  64. }
  65. return req;
  66. }
  67. /**
  68. * Create a new http request for customization and add session tokens to header.
  69. *
  70. * @param method request type
  71. * @param uri to web service to prepended with configuration api endpoint
  72. * @param body request data
  73. * @returns {Request}
  74. */
  75. private newRequest(method: RequestMethod, uri: string | Request, body?: any): Request {
  76. let req: Request;
  77. if (typeof uri === 'string') {
  78. req = this.blankRequest(method, uri, body);
  79. req.headers = new Headers();
  80. } else {
  81. req = <Request>uri;
  82. req.headers = req.headers || new Headers();
  83. }
  84. req.url = environment.apiEndpoint + environment.apiPrefix + req.url;
  85. const sessionID = this.sessionService.getSessionID();
  86. if (sessionID) {
  87. req.headers.append(environment.sessionTokenName, sessionID);
  88. }
  89. if(body){
  90. req.headers.append('Content-Type', 'text/json');
  91. req.headers.append('Accept', 'text/json');
  92. }
  93. return req;
  94. }
  95. /**
  96. * Handle error with error logging.
  97. *
  98. * For 401 clear session token and redirect to the login page.
  99. *
  100. * @param error result from http request
  101. * @param req original request
  102. * @returns {Promise<Response>}
  103. */
  104. private handleError(error: any, req: Request): Promise<Response> {
  105. if (error.status && error.status === 401) {
  106. this.sessionService.removeSessionID();
  107. this.router.navigate(['/login']);
  108. } else {
  109. this._logger.error('An error occurred' + JSON.stringify(req, null, 2) + error);
  110. }
  111. return Promise.reject(error.message || error);
  112. }
  113. /**
  114. * Perform given request only using prepopulated request Request.
  115. *
  116. * @param req Request
  117. */
  118. private request(req: Request): Promise<any> {
  119. return this.http.request(req)
  120. .toPromise()
  121. .then((response: Response) => {
  122. return response.text().length ? response.json() : null;
  123. })
  124. .catch((error: any) => this.handleError(error, req));
  125. }
  126. }

Step #2

Now, the created common proxy service class needs to be registered to a root module. We do this to it so that it can be available throughout the application.

src\app\core\ core.module.ts

  1. import { ProxyService } from './services/ProxyService/proxy.service';
  2. @NgModule({
  3. imports: [
  4. ],
  5. declarations: [
  6. ],
  7. providers: [
  8. ProxyService
  9. ],
  10. exports: [
  11. ],
  12. entryComponents: [
  13. ]
  14. })
  15. export class CoreModule {
  16. }

Step #3

Once the common proxy service is created and registered in the root module, we can use it in any service creation by simply importing and injecting it as a dependency injection in the constructor of the newly created Service class.

Below is the sample code snippet for the service class creation and utilization of the common proxy service class inside newly created service class.

  1. import { Observable } from 'rxjs/Rx';
  2. import { Injectable } from '@angular/core';
  3. import { ProxyService } from 'app/core/services/ProxyService/proxy.service';
  4. @Injectable()
  5. export class TestService {
  6. constructor(private proxyService: ProxyService) { }
  7. // post data to Api
  8. saveTestCode(casePayment: any): Observable<any> {
  9. return Observable.fromPromise(this.proxyService.put('TestCode/UpsertTestCode', testId));
  10. }
  11. getTestCode(testId: number): Observable<any> {
  12. return Observable.fromPromise(this.proxyService.get(TestCode/GetTestCodeById?testId=' + testId));
  13. }
  14. }

In my upcoming articles, I am going to show you a demo application to demonstrate all our learnings on Angular.

I would appreciate your valuable comments.

<<Click here for the previous article