base-data.service.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import { HttpClient } from '@angular/common/http';
  2. import { Injectable } from '@angular/core';
  3. import { Apollo } from 'apollo-angular';
  4. import { DataProxy } from 'apollo-cache';
  5. import { FetchPolicy } from 'apollo-client';
  6. import { ExecutionResult } from 'apollo-link';
  7. import { DocumentNode } from 'graphql/language/ast';
  8. import { Observable } from 'rxjs';
  9. import { map } from 'rxjs/operators';
  10. import { CustomFields } from 'shared/shared-types';
  11. import { API_URL } from '../../app.config';
  12. import { LocalStorageService } from '../../core/providers/local-storage/local-storage.service';
  13. import { addCustomFields } from '../add-custom-fields';
  14. import { QueryResult } from '../query-result';
  15. import { ServerConfigService } from '../server-config';
  16. /**
  17. * Make the MutationUpdaterFn type-safe until this issue is resolved: https://github.com/apollographql/apollo-link/issues/616
  18. */
  19. export type TypedFetchResult<T = Record<string, any>> = ExecutionResult & {
  20. context?: T;
  21. data: T;
  22. };
  23. export type TypedMutationUpdateFn<T> = (proxy: DataProxy, mutationResult: TypedFetchResult<T>) => void;
  24. @Injectable()
  25. export class BaseDataService {
  26. constructor(
  27. private apollo: Apollo,
  28. private httpClient: HttpClient,
  29. private localStorageService: LocalStorageService,
  30. private serverConfigService: ServerConfigService,
  31. ) {}
  32. private get customFields(): CustomFields {
  33. return this.serverConfigService.serverConfig.customFields || {};
  34. }
  35. /**
  36. * Performs a GraphQL watch query
  37. */
  38. query<T, V = Record<string, any>>(
  39. query: DocumentNode,
  40. variables?: V,
  41. fetchPolicy: FetchPolicy = 'cache-and-network',
  42. ): QueryResult<T, V> {
  43. const withCustomFields = addCustomFields(query, this.customFields);
  44. const queryRef = this.apollo.watchQuery<T, V>({
  45. query: withCustomFields,
  46. variables,
  47. fetchPolicy,
  48. });
  49. return new QueryResult<T, any>(queryRef);
  50. }
  51. /**
  52. * Performs a GraphQL mutation
  53. */
  54. mutate<T, V = Record<string, any>>(
  55. mutation: DocumentNode,
  56. variables?: V,
  57. update?: TypedMutationUpdateFn<T>,
  58. ): Observable<T> {
  59. const withCustomFields = addCustomFields(mutation, this.customFields);
  60. return this.apollo
  61. .mutate<T, V>({
  62. mutation: withCustomFields,
  63. variables,
  64. update: update as any,
  65. })
  66. .pipe(map(result => result.data as T));
  67. }
  68. /**
  69. * Perform REST-like POST
  70. */
  71. post(path: string, payload: Record<string, any>): Observable<any> {
  72. return this.httpClient
  73. .post(`${API_URL}/${path}`, payload, {
  74. headers: {
  75. Authorization: this.getAuthHeader(),
  76. },
  77. observe: 'response',
  78. })
  79. .pipe(map(response => response.body));
  80. }
  81. /**
  82. * Perform REST-like GET
  83. */
  84. get(path: string): Observable<any> {
  85. return this.httpClient
  86. .get(`${API_URL}/${path}`, {
  87. headers: {
  88. Authorization: this.getAuthHeader(),
  89. },
  90. observe: 'response',
  91. })
  92. .pipe(map(response => response.body));
  93. }
  94. private getAuthHeader(): string {
  95. const authToken = this.localStorageService.get('authToken');
  96. return `Bearer ${authToken}`;
  97. }
  98. }