簡體   English   中英

如何在 Angular8 中創建通用請求服務

[英]How to make a generic request service in Angular8

我創建了一個通用請求服務,但它不斷返回“ZoneAwarePromise”。 我嘗試使用 .pipe() 和 .subscribe() 來嘗試檢索請求的內容,但它不起作用。

requester.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

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

  constructor(private http: HttpClient) { }

  request(method, url, headers, body, params) {
    return this.http.request(method, url, {
      body: body || {},
      headers: headers || {},
      params: params || {}
    })
  }

  async get(url, params?, headers?, data?) {
    return await this.request('get', url, params, headers, data)
  }

  async post(url, params, headers, data) {
    return await this.request('post', url, params, headers, data);
  }

  async put(url, params, headers, data) {
    return await this.request('put', url, params, headers, data);
  }

  async delete(url, params, headers, data) {
    return await this.request('delete', url, params, headers, data);
  }
}

健身房-list.component.ts

import { Component, OnInit } from '@angular/core';
import { RequesterService } from 'src/app/core/Requester/requester.service';

@Component({
  selector: 'app-gym-list',
  templateUrl: './gym-list.component.html',
  styleUrls: ['./gym-list.component.css']
})
export class GymListComponent implements OnInit {

  constructor(private Requester: RequesterService) { }

  ngOnInit() {
    console.log(this.teste())
  }

  async teste() {
    await this.Requester.get('https://searchs.glitch.me/proposalcontent')
  }
}
import { HttpClient, HttpHeaders, HttpRequest, HttpEventType, HttpEvent, HttpResponse, HttpErrorResponse } from "@angular/common/http";
import { Observable, from } from 'rxjs';
import { IGenericHttpClient } from './igeneric-http-client';
import { Injectable } from '@angular/core';
import { HttpMethod } from '../view-models/component-type.enum'
import { IRequestOptions } from '../view-models/interface';
import { EnvironmentViewModel } from '../view-models/environment-view-model';
import { retry } from 'rxjs/operators';
@Injectable()
export class GenericHttpClient<T> implements IGenericHttpClient<T>{

  constructor(private httpClient: HttpClient, private environment: EnvironmentViewModel) { }

  public Post(destinationUrl: string, options?: IRequestOptions): Observable<T> {
    return this.request<T>(HttpMethod.Post, destinationUrl, options);
  }

  public Put(destinationUrl: string, options?: IRequestOptions): Observable<T> {
    return this.request<T>(HttpMethod.Put, destinationUrl, options);
  }

  public Get(destinationUrl: string, options?: IRequestOptions): Observable<T> {
    return this.request<T>(HttpMethod.Get, destinationUrl, options);
  }

  public Delete(destinationUrl: string, options?: IRequestOptions): Observable<T> {
    return this.request<T>(HttpMethod.Delete, destinationUrl, options);
  }

  private request<T>(method: string, url: string, options?: IRequestOptions): Observable<T> {
    return Observable.create((observer: any) => {
      this.httpClient.request<T>(new HttpRequest(method, this.environment.baseUrl + url, options)).subscribe(
        (response: any) => {
          const responsTye = response as HttpEvent<any>
          switch (responsTye.type) {
            case HttpEventType.Sent:
              console.log('Request sent!');
              break;
            case HttpEventType.ResponseHeader:
              console.log('Response header received!');
              break;
            case HttpEventType.DownloadProgress:
              const kbLoaded = Math.round(responsTye.loaded / 1024);
              console.log(`Download in progress! ${kbLoaded}Kb loaded`);
              break;
            case HttpEventType.Response:
              observer.next(response.body);
              console.log('😺 Done!', responsTye.body);
          }
        },
        (error) => {
          switch (error.status) {
            case 403:
              observer.complete();
              break;
            default:
              observer.error(error);
              break;
          }
        }
      );
    });
  }
}

您正在嘗試使用 await 返回一個非異步函數。

  request(method, url, headers, body, params) {
    return this.http.request(method, url, {
      body: body || {},
      headers: headers || {},
      params: params || {}
    })
  }

  async get(url, params?, headers?, data?) {
    return await this.request('get', url, params, headers, data)
  }

你不應該在這里使用 async-await 系統。

嘗試這個:

  get(url, params?, headers?, data?) {
    return this.request('get', url, params, headers, data)
  }

並在您的 component.ts 文件中訂閱此方法。

像這樣:

Requester.get.subscribe(....)

實際上,您可以創建一個可以在任何服務中擴展的抽象基礎服務類。 這將通過調用另一個具有通用錯誤處理代碼的服務來自動處理錯誤。 如果傳遞customError標志,則錯誤將返回到組件中以處理自定義錯誤。 此方法使用RxJs Observables ,它可以在 component.ts 中訂閱並捕獲響應和錯誤。

import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";
import { tap } from "rxjs/operators";

import { HttpOptionsService } from "../../services/httpoptions.service";

export abstract class ServiceBase {
  constructor(
    private http: HttpClient,
    private httpOptionService: HttpOptionsService
  ) {}

  httpOptions = {
    headers: new HttpHeaders({
      "Content-Type": "application/json"
    })
  };

  getFormattedPostRequest(
    url: string,
    body: any,
    customError: boolean = false): Observable<any> {
    return this.pipeTapObservable(
      this.http.post(url, body, this.httpOptions),
      customError
    );
  }

  getFormattedPutRequest(
    url: string,
    body: any,
    customError: boolean = false
  ): Observable<any> {
    return this.pipeTapObservable(
      this.http.put(url, body, this.httpOptions),
      customError
    );
  }

  getFormattedGetRequest(
    url: string,
    customError: boolean = false
  ): Observable<any> {
    return this.pipeTapObservable(
      this.http.get(url, this.httpOptions),
      customError
    );
  }

  getFormattedDeleteRequest(
    url: string,
    customError: boolean = false
  ): Observable<any> {
    return this.pipeTapObservable(
      this.http.delete(url, this.httpOptions),
      customError
    );
  }

  private pipeTapObservable(
    request: Observable<any>,
    customError: boolean = false
  ): Observable<any> {
    return request.pipe(
      tap(
        response => response,
        error => {
          !customError &&
            this.httpOptionService.handleError(error);
          return error;
        }
      )
    );
  }
}

如果您要添加一些常見的標頭,您可以創建一個攔截器來添加它們。 您可以在如下所示的任何服務中使用它。

 @Injectable()
    export class MyService extends ServiceBase {
      constructor(
        http: HttpClient,
        httpOptionService: HttpOptionsService
    ) {
        super(http, httpOptionService);
      }
   }

您可以使用 async/await 但此語法適用於承諾類型和請求方法返回一個可觀察對象,因此您只需要從請求方法返回一個承諾,或者您可以在 get、post、put、delete 方法的 return 語句上執行此操作

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

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

  constructor(private http: HttpClient) { }

  request(method, url, headers, body, params) {
    return this.http.request(method, url, {
      body: body || {},
      headers: headers || {},
      params: params || {}
    }).toPromise();
  }

   get(url, params?, headers?, data?) {
    return this.request('get', url, params, headers, data);
  }

   post(url, params, headers, data) {
    return this.request('post', url, params, headers, data);
  }

   put(url, params, headers, data) {
    return this.request('put', url, params, headers, data);
  }

   delete(url, params, headers, data) {
    return this.request('delete', url, params, headers, data);
  }
}

成分

import { Component, OnInit } from '@angular/core';
import { RequesterService } from 'src/app/core/Requester/requester.service';

@Component({
  selector: 'app-gym-list',
  templateUrl: './gym-list.component.html',
  styleUrls: ['./gym-list.component.css']
})
export class GymListComponent implements OnInit {

  constructor(private Requester: RequesterService) { }

  ngOnInit() {
    console.log(this.teste())
  }

  async teste() {
    const result = await this.Requester.get('https://searchs.glitch.me/proposalcontent');

    console.log(result); 👈
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM