Наличие перехвата чтения кэшированного значения - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь прочитать перехватчик из моего кэша, чтобы проверить, был ли кеширован почтовый запрос, когда я не в сети. Если это так, я бы вместо этого вернул кэшированные локальные данные и отобразил бы их. Кеш использует кеш-память Ionic.

В этом примере у меня просто проверяется один шаблон URL (api / dfrs / id), и это значение кэшируется. Я перебираю кеш и получаю значение, если установлен определенный ключ. Каждое значение кэша является самим запросом post.

Значение в конечном итоге найдено, но поскольку метод для получения значения является асинхронным, код перехватчика продолжается до возвращения кэшированного результата.

Итак, две проблемы, которые я пытаюсь решить

1) Выполнить код в первом операторе if для этого метода обещания

2) Вернуть тело кэшированного запросакак наблюдаемый, так что мой взгляд может использовать его

Любая помощь будет очень признательна.

token.interceptor

`

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';

import { Observable, throwError, BehaviorSubject, from, EMPTY, NEVER, of } from 'rxjs';
import { catchError, filter, take, switchMap, finalize, map } from 'rxjs/operators';
import { AuthService } from '../admin/users/auth.service';
import { Router } from '@angular/router';
import { Storage, IonicStorageModule } from '@ionic/storage';
import { CacheSaveDataService } from './cache-save-data.service';

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  private isRefreshing = false;
  private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);

  constructor(public authService: AuthService, public cacheSaveDataService: CacheSaveDataService) { }

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (!this.cacheSaveDataService.status.connected && request.method === 'GET' &&
      request.url.indexOf('api/dfrs/id/') !== -1) {
      return next.handle(request).pipe (
        map((event: any) => {
          let val = this.getCachedResult(request);
          return (Observable.create(val));
        })
      )

    } else if (!this.cacheSaveDataService.status.connected && request.url.indexOf('authenticate') === -1
      && request.url.indexOf('logout') === -1  && (request.method === 'PUT' || request.method === 'POST')) {

      const result = this.cacheSaveDataService.setStorageRequest(request);

      return next.handle(request).pipe(
        map((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                console.log('event--->>>', event);
            }
            return event;
        }),
        catchError((error: HttpErrorResponse) => {
            let data = {};
            data = {
                reason: error && error.error && error.error.reason ? error.error.reason : '',
                status: error.status
            };
            return throwError(error);
        }));

    } else {
      const userId = this.getUserId();
      if (this.authService.getJwtToken()) {
        request = this.addToken(request, this.authService.getJwtToken(), userId);
      }

      return next.handle(request).pipe(catchError(error => {
        if (error instanceof HttpErrorResponse && error.status === 401) {
          return this.handle401Error(request, next);
        } else {
            if (error.status === 405) { //|| error.status === 500) {
              this.authService.backToLogin();
            }
          console.log('error, not logged in');
          return throwError(error);
        }
      }));
    }
    console.log ('Done Intercepter');
  }

  async getCachedResult(request) {
    const keys = await this.cacheSaveDataService.getKeys();
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      if (key.indexOf('reqcache') !== -1) {
        return  await this.getKeyValue(key, request);
      }
    }
  }

  async getKeyValue(key, request) {
    const res = await this.cacheSaveDataService.get2(key);
    const val: any = res;

    if (val.url === request.url) {
      return val;
    }
  }

  private addToken(request: HttpRequest<any>, token: string, userId: string) {
    const headers = new HttpHeaders({
      'Authorization': `Bearer ${token}`,
      'userId': userId
    });
    return request.clone({headers});
  }

  private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
    const userId = this.getUserId();
    if (!this.isRefreshing) {
      this.isRefreshing = true;
      this.refreshTokenSubject.next(null);

      return this.authService.refreshToken().pipe(
        switchMap((token: any) => {
          this.isRefreshing = false;
          this.refreshTokenSubject.next(token.jwt);
          return next.handle(this.addToken(request, token.jwt, userId));
        }));

    } else {
      return this.refreshTokenSubject.pipe(
        filter(token => token != null),
        take(1),
        switchMap(jwt => {
          return next.handle(this.addToken(request, jwt, userId));
        }));
    }
  }

  private getUserId() {
    const user: any = JSON.parse(localStorage.getItem('user') );
    let userId = '0';
    if (user !== undefined && user !== null) {
      userId = user._id;
    }
    return userId;
  }

}

`

cache-save-data.service.ts `

import { Injectable } from '@angular/core';
import { Storage, IonicStorageModule } from '@ionic/storage';
import { Network } from '@capacitor/core';
import { HttpClient } from '@angular/common/http';
import { SharedService } from '../shared/shared.service';
import { DFRPhotoService } from '../dfr/daily-summary/dfr-photo/dfr-photo.service';
import { LoadingController } from '@ionic/angular';

@Injectable({
  providedIn: 'root'
})
export class CacheSaveDataService {

  status = null;
  handler;
  loaderElement;

  constructor(
      public storage: Storage,
      private httpClient: HttpClient,
      private sharedService: SharedService,
      private loadingController: LoadingController) {

    this.status = this.getStatus();
    if (this.handler === undefined) {
      console.log('Add Listener ', status);
      this.handler = Network.addListener('networkStatusChange', (status) => {
        console.log('Network status changed! ', status);
        const oldStatus = this.status;
        this.status = status;
        if (this.status.connected && !oldStatus.connected) {
          this.saveCachedData();
        }
        this.status = status;
        if (!this.status.connected) {
          this.sharedService.showNotification('Network connection has terminated.', 'danger', 5000);
        }
      });
    }
  }



  public async setItem(key, value) {
    return await this.storage.set(key, value);
  }

  public async setStorageRequest2(request) {
    const cacheKey = 'reqcache-' + this.sharedService.generateId();
    return await this.storage.set(cacheKey, request);
  }

  public async setStorageRequest(request) {
    this.sharedService.showNotification('User is offline. Service Request Cached', 'warning', 2000);
    const cacheKey = 'reqcache-' + this.sharedService.generateId() + '-' + request.urlWithParams;
    return await this.storage.set(cacheKey, request);
  }

  public async get(settingName){
    return await this.storage.get(`setting:${ settingName }`);
  }

  public async get2(settingName) {
    return await this.storage.get(settingName);
  }

  public async remove(settingName){
    return await this.storage.remove(settingName);
  }

  public clear() {
    this.storage.clear().then(() => {
      console.log('all keys cleared');
    });
  }

  public async getKeys() {
    return await this.storage.keys();
  }

  public async getStatus() {
    this.status = await Network.getStatus();
  }


}

`

// dfr.service.ts (метод только в классе)`

public getDFRByDfrId(id: string) {
    return this.httpClient.get(environment.apiURL + this.path + '/id/' + id)
    .pipe(
      map((res: any) => {
        return res.data;
      })
    );
  }

`

// view.ts (только подписка)`

   this.dfrService.getDFRByDfrId(paramMap.get('id')).subscribe(val => {
               this.currentDFR = val;
            });

`

Я ожидаю, что тело моего кэшированного запроса будет возвращено

1 Ответ

0 голосов
/ 02 октября 2019

LOL наконец получил это. Я был не в состоянии выслушать обещание и затем должен вернуть наблюдаемое. Надеюсь, это кому-нибудь поможет: 0

замените этот код

return next.handle(request).pipe (
    map((event: any) => {
      let val = this.getCachedResult(request);
      return (Observable.create(val));
    })
  )

на

return from(this.getCachedResult(request)).pipe (
      mergeMap(data => {
         return of(new HttpResponse({ body: data.body }))
      })
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...