Angular8 HttpClient 30分鐘深刻了解下


Angular8 HttpClient 30分鐘深刻了解下

前端開發,axios是標配的http請求發起libary, 採用的是Promise的方式。而後,Angular中採用的是另一種形式Observable,觀察訂閱模式。Angular默認推薦採用內置的HTTPClient。 下面讓咱們開始今天的主題,HTTPClient前端

模塊引入

import {HttpClientModule} from '@angular/common/http';
@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        HttpClientModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {
}
複製代碼

入門

GET請求

指定請求返回類型
this.http.get<Config>(this.configUrl)
  .subscribe((data: Config) => this.config = { ...data });
複製代碼
  • get請求,明確返回的數據類型爲Config,故請求形式爲:
this.http.get<Config>()...
複製代碼
  • 請求返回後,進行數據轉換
不指定請求返回類型
this.http.get(this.configUrl)
.subscribe((data: any) => this.config = { ...data });
複製代碼

等效於ios

this.http.get<Object>(this.configUrl)
.subscribe((data: Object) => this.config = { ...data });
複製代碼

問題1: 若是服務端,返回的數據就是一個text文本,譬如Hello,world,你猜會怎麼樣?web

請求url攜帶參數
  • 方法一:HttpParams 形式set
# 必須.鏈式set,不然參數空
const params = new HttpParams()
    .set('orderBy', '"$key"')
    .set('limitToFirst', "1");
this.http.get(this.configUrl,{params})
  .subscribe((data: any) => this.config = { ...data });
複製代碼
  • 方法二: fromString

編程

const params = new HttpParams({ fromString: 'orderBy="$key"&limitToFirst=1' }); 複製代碼this.http.get(this.configUrl,{params}) .subscribe((data: any) => this.config = { ...data }); 複製代碼

問題2: 若是前端想拿到後端api header頭中參數,怎麼辦?json

POST

this.http.post(url,
    {
        "courseListIcon": "...",
        "description": "TEST",
        "iconUrl": "..",
        "longDescription": "...",
        "url": "new-url"
    })
    .subscribe(
        (res) => {
            console.log("POST call successful value returned in body", 
                        res);
        },
        error => {
            console.log("POST call in error", error);
        },
        () => {
            console.log("The POST observable is now completed.");
        });
}
複製代碼

DELETE

this.http.delete(url1)
    .subscribe(
        (res) => {
            console.log("DELETE call successful value returned in body", 
                        res);
        },
        error => {
            console.log("DELETE call in error", error);
        },
        () => {
            console.log("The DELETE observable is now completed.");
        });
}
複製代碼

PATCH

this.http.patch(url,
    {
        "description": "Angular Tutorial For Beginners PATCH TEST",
    })
    .subscribe(
        (res) => {
            console.log("PATCH call successful value returned in body", 
                        res);
        },
        error => {
            console.log("PATCH call in error", error);
        },
        () => {
            console.log("The PATCH observable is now completed.");
        });
}
複製代碼

進階

GET請求

request方式傳參
const params = new HttpParams({
 fromString: 'orderBy="$key"&limitToFirst=1'
});
this.http.request("GET",this.configUrl, { params })
複製代碼
header傳參
  • 方法一: HttpHeaders
const headers = new HttpHeaders()
         .set("X-CustomHeader", "custom header value");
this.http.get(this.configUrl,{ headers })
 .do(console.log)
 .map(data => _.values(data));
複製代碼
  • 方法二:{} 字面量
const headers = {
  "X-CustomHeader", "custom header value",
  'content-type': 'application/json'
}
this.http.get(this.configUrl,{ headers })
 .do(console.log)
 .map(data => _.values(data));
複製代碼
解答問題1:
  • 咱們看一下源碼針對Get方法請求參數的定義
get(url: string, options?: {
      headers?: HttpHeaders | {
          [header: string]: string | string[];
      };
      # 默認值有: response| body| event 
      observe?: 'body';# 默認讀取的是response中的body 
      params?: HttpParams | {
          [param: string]: string | string[];
      };
      reportProgress?: boolean;
      # 默認值有: arraybuffer | json | blob |text
      responseType?: 'json';# 這裏,ts參數類型可選,默認值json,
      withCredentials?: boolean;
  }): Observable<Object>;
複製代碼
  • 故從源碼咱們能夠知道,後端返回Hello,world,前端get方法會返回JSON解析異常。此時咱們設置下responseType便可。
this.http.get(this.configUrl,{responseType:'text'})
.subscribe((data: any) => this.config = { ...data });
複製代碼
解答問題二:
this.http.get<Config>(
     this.configUrl, { observe: 'response' })
    .subscribe((data: any) => this.config = { ...data });
複製代碼
那麼event 是幹什麼的呢?
const request = new HttpRequest(
        "POST", this.uploadURL, {},{observe: 'events',reportProgress: true});
    this.http.request(request)
        .subscribe(
            event => {
                # 文件上傳進度斷定
                if (event.type === HttpEventType.DownloadProgress) {
                    console.log("Download progress event", event);
                }
                if (event.type === HttpEventType.UploadProgress) {
                    console.log("Upload progress event", event);
                }
                if (event.type === HttpEventType.Response) {
                    console.log("response received...", event.body);
                }
            }
        );
複製代碼

高級

GET請求

並行多個Get處理
const parallel$ = Observable.forkJoin(
        this.http.get(url1),
        this.http.get(url2)
    );
parallel$.subscribe(
    values => {
        console.log("all values", values)
    }
);
複製代碼
串行多個Get請求
const sequence$ = this.http.get<Config>(url1)
    .switchMap(config => {
        config.description+= ' - TEST ';
        return this.http.put(url2,config)
    });
sequence$.subscribe(
    values => console.log("result observable ", values) 
);
複製代碼
異常處理
this.http
    .get("/api/simulate-error")
    .catch( error => {
        // here we can show an error message to the user,
        // for example via a service
        console.error("error catched", error);
        return Observable.of({description: "Error Value Emitted"});
    })
    .subscribe(
        val => console.log('Value emitted successfully', val),
        error => {
            console.error("This line is never called ",error);
        },
        () => console.log("HTTP Observable completed...")
    );
複製代碼
請求攔截
  • 定義鑑權攔截器
import {Injectable} from "@angular/core";
import {HttpEvent, HttpHandler, HttpInterceptor} 
     from "@angular/common/http";
import {HttpRequest} from "@angular/common/http";
import {Observable} from "rxjs/Observable";
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
    constructor(private authService: AuthService) {
    }
    intercept(req: HttpRequest<any>, 
               next: HttpHandler):Observable<HttpEvent<any>> {
        const clonedRequest = req.clone({
            headers: req.headers.set(
                'X-CustomAuthHeader', 
                authService.getToken())
        });
        console.log("new headers", clonedRequest.headers.keys());
        return next.handle(clonedRequest);
    }
}
複製代碼
  • 配置攔截器
@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        HttpClientModule
    ],
    providers: [
        [ 
           { 
            provide: HTTP_INTERCEPTORS, 
            useClass: AuthInterceptor,
            multi: true 
          }
        ]
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}
複製代碼

參考

推薦

Angular8狀態管理NgRx

前端Rollup+RxJs響應式編程實踐

Angular8 httpclient簡單入門

20個你值得了解的Angular開源項目

angular8 平常開發填坑指南

Angular開發必備插件一覽表

相關文章
相關標籤/搜索