interceptor.ts 3.63 KB
Newer Older
Trần Anh Phú's avatar
Trần Anh Phú committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
import {
  HttpContextToken,
  HttpErrorResponse,
  HttpEvent,
  HttpEventType,
  HttpHandlerFn,
  HttpInterceptorFn,
  HttpRequest,
  HttpResponse,
  HttpStatusCode,
} from '@angular/common/http';
import { environment } from '../../../../environments/environment.development';
import { catchError, EMPTY, Observable, tap, throwError } from 'rxjs';
import { ResponseResult } from '../../data-access/interface/response.type';

export const SHOW_LOADING = new HttpContextToken<boolean>(() => true);
export const SHOW_API_MESSAGE = new HttpContextToken<boolean>(() => true);
export const SHOW_API_ERROR_MESSAGE = new HttpContextToken<boolean>(() => true);

export const interceptors: HttpInterceptorFn = (
  req: HttpRequest<unknown>,
  next: HttpHandlerFn
): Observable<HttpEvent<unknown>> => {
  const showLoading = req.context.get(SHOW_LOADING);
  const showApiMessage = req.context.get(SHOW_API_MESSAGE);
  const showApiErrorMessage = req.context.get(SHOW_API_ERROR_MESSAGE);
  const token = localStorage.getItem('token'); //custom
  req = req.clone({
    url: !req.url.includes('http') ? environment.API_DOMAIN + req.url : req.url,
    setHeaders: {
      Authorization: `Bearer ${token ? token : ''}`,
      StandardTimeZoneName: `${
        Intl.DateTimeFormat().resolvedOptions().timeZone
      }`,
    },
  });
  runIf(showLoading, () => {});
  return next(req).pipe(
    tap({
      next: (response) => {
        if (response.type === HttpEventType.Response) {
          if (response && response.body) {
            const apiType = checkApiType(response);
            if (apiType === 'success') {
              const resp = response.body as ResponseResult<unknown>;
              runIf(
                showApiMessage && !!resp.message && req.method !== 'GET',
                () => {}
              );
            } else if (apiType === 'error') {
              const resp = response.body as ResponseResult<unknown>;
              runIf(!resp.success && !!resp.message, () => {});
            }
          }
        }
      },
      finalize: () => runIf(showLoading, () => {}),
    }),
    catchError(
      (error: HttpErrorResponse, _: Observable<HttpEvent<unknown>>) => {
        const apiError = error.error as ResponseResult<unknown> | Blob | null;
        if (apiError instanceof Blob) {
          apiError.text().then((val) => {
            const errors = JSON.parse(val);
            runIf(showApiErrorMessage, () => {
              //   console.log('error: ', val);
            });
          });
          return EMPTY;
        }

        if (error.status === HttpStatusCode.InternalServerError) {
          //   console.log('error: InternalServerError');
          return EMPTY;
        }

        // sandbox api
        if (error.error === '404 Page Not Found' && showApiErrorMessage) {
          //   console.log('error: ', error.error);
          return EMPTY;
        }

        // if (error.status === HttpStatusCode.Unauthorized) {
        //   // authStore.signOut();
        //   //   console.log('error: Unauthorized');
        //   return EMPTY;
        // }

        if (error.status === HttpStatusCode.Forbidden) {
          //authStore.signOut();
          //   console.log('error: Forbidden');
          return EMPTY;
        }

        if (!apiError?.message) {
          //   console.log('error: ???');
          return EMPTY;
        }
        return throwError(() => apiError);
      }
    )
  );
};

function runIf(isShowMessage: boolean, func: () => void) {
  if (isShowMessage) {
    func();
  }
}

function checkApiType(
  httpResponse: HttpResponse<unknown>
): 'success' | 'error' {
  return Object.hasOwn(httpResponse.body as object, 'res')
    ? 'error'
    : 'success';
}