HttpClientModule 应用
导入新的 HTTP Module
import {HttpClientModule} from '@angular/common/http' ;
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
需要注意的是,现在 JSON 是默认的数据格式,我们不需要再进行显式的解析。即我们不需要再使用以下代码:
http.get(url).map(res => res.json()).subscribe(...)
现在我们可以这样写:
http.get(url).subscribe(...)
?
发送 Get 请求
import {Component, OnInit} from '@angular/core' ;
import {Observable} from "rxjs/Observable" ;
import {HttpClient} from "@angular/common/http" ;
import * as _ from 'lodash' ;
interface Course {
description: string;
courseListIcon:string;
iconUrl:string;
longDescription:string;
url:string;
}
@Component({
selector: 'app-root' ,
template: `
<ul *ngIf="courses$ | async as courses else noData">
<li *ngFor="let course of courses">
{{course.description}}
</li>
</ul>
<ng-template #noData>No Data Available</ng-template>
`})
export class AppComponent implements OnInit {
courses$: Observable <any> ;
constructor(private http:HttpClient) {}
ngOnInit() {
this .courses$ = this .http
.get( "https://angular-http-guide.firebaseio测试数据/courses.json" )
.map(data => _.values(data))
. do (console.log);
}
}
?
设置查询参数
假设发送 Get 请求时,需要设置对应的查询参数,预期的 URL 地址如下:
https: // angular-http-guide.firebaseio测试数据/courses.json?orderBy="$key"&limitToFirst=1创建 HttpParams 对象
import {HttpParams} from "@angular/common/http" ;
const params = new HttpParams()
.set( 'orderBy', '"$key"' )
.set( 'limitToFirst', "1" );
this .courses$ = this .http
.get( "/courses.json" , {params})
. do (console.log)
.map(data => _.values(data))
需要注意的是,我们通过链式语法调用? set() ?方法,构建? HttpParams ?对象。这是因为? HttpParams ?对象是不可变的,通过? set() ?方法可以防止该对象被修改。
每当调用? set() ?方法,将会返回包含新值的? HttpParams ?对象,因此如果使用下面的方式,将不能正确的设置参数。
const params = new HttpParams(); params.set( 'orderBy', '"$key"' ) params.set( 'limitToFirst', "1");使用? fromString ?语法
const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'});
使用? request() ?API
const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1' });
this .courses$ = this .http
.request(
"GET" ,
"/courses.json" ,
{
responseType: "json" ,
params
})
. do (console.log)
.map(data => _.values(data));
?
设置 HTTP Headers
const headers = new HttpHeaders().set("X-CustomHeader", "custom header value" );
this .courses$ = this .http
.get(
"/courses.json" ,
{headers})
. do (console.log)
.map(data => _.values(data));
?
发送 Put 请求
httpPutExample() {
const headers = new HttpHeaders().set("Content-Type", "application/json" );
this .http.put("/courses/-KgVwECOnlc-LHb_B0cQ.json" ,
{
"courseListIcon": ".main-page-logo-small-hat.png" ,
"description": "Angular Tutorial For Beginners TEST" ,
"iconUrl": ".angular2-for-beginners.jpg" ,
"longDescription": "..." ,
"url": "new-value-for-url"
},
{headers})
.subscribe(
val => {
console.log( "PUT call successful value returned in body" ,
val);
},
response => {
console.log( "PUT call in error" , response);
},
() => {
console.log( "The PUT observable is now completed." );
}
);
}
?
发送 Patch 请求
httpPatchExample() {
this .http.patch("/courses/-KgVwECOnlc-LHb_B0cQ.json" ,
{
"description": "Angular Tutorial For Beginners PATCH TEST" ,
})
.subscribe(
(val) => {
console.log( "PATCH call successful value returned in body" ,
val);
},
response => {
console.log( "PATCH call in error" , response);
},
() => {
console.log( "The PATCH observable is now completed." );
});
}
?
发送 Delete 请求
httpDeleteExample() {
this .http. delete ("/courses/-KgVwECOnlc-LHb_B0cQ.json" )
.subscribe(
(val) => {
console.log( "DELETE call successful value returned in body" ,
val);
},
response => {
console.log( "DELETE call in error" , response);
},
() => {
console.log( "The DELETE observable is now completed." );
});
}
?
发送 Post 请求
httpPostExample() {
this .http.post("/courses/-KgVwECOnlc-LHb_B0cQ.json" ,
{
"courseListIcon": "..." ,
"description": "TEST" ,
"iconUrl": ".." ,
"longDescription": "..." ,
"url": "new-url"
})
.subscribe(
(val) => {
console.log( "POST call successful value returned in body" ,
val);
},
response => {
console.log( "POST call in error" , response);
},
() => {
console.log( "The POST observable is now completed." );
});
}
?
避免重复请求
duplicateRequestsExample() {
const httpGet$ = this .http
.get( "/courses.json" )
.map(data => _.values(data));
httpGet$.subscribe(
(val) => console.log("logging GET value" , val)
);
this .courses$ = httpGet$;
}
在上面例子中,我们正在创建了一个 HTTP observable 对象? httpGet$ ,接着我们直接订阅该对象。然后,我们把? httpGet$ ?对象赋值给? courses$ ?成员变量,最后在模板中使用? async ?管道订阅该对象。
这将导致发送两个 HTTP 请求,在这种情况下,请求显然是重复的,因为我们只希望从后端查询一次数据。为了避免发送冗余的请求,我们可以使用 RxJS 提供的? shareReplay ?操作符:
// put this next to the other RxJs operator imports
import 'rxjs/add/operator/shareReplay' ;
const httpGet$ = this .http
.get( "/courses.json" )
.map(data => _.values(data))
.shareReplay();
?
并行发送多个请求
并行发送 HTTP 请求的一种方法是使用 RxJs 中的? forkjoin ?操作符:
import 'rxjs/add/observable/forkJoin' ;
parallelRequests() {
const parallel$ = Observable.forkJoin(
this .http.get('/courses/-KgVwEBq5wbFnjj7O8Fp.json' ),
this .http.get('/courses/-KgVwECOnlc-LHb_B0cQ.json' )
);
parallel$.subscribe(
values => {
console.log( "all values" , values)
}
);
}
?
顺序发送 Http 请求
sequentialRequests() {
const sequence$ = this .http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json' )
.switchMap(course => {
course.description += ' - TEST ' ;
return this .http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json' , course)
});
sequence$.subscribe();
}
?
获取顺序发送 Http 请求的结果
sequentialRequests() {
const sequence$ = this .http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json' )
.switchMap(course => {
course.description += ' - TEST ' ;
return this .http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json' , course)
},
(firstHTTPResult, secondHTTPResult) => [firstHTTPResult, secondHTTPResult]);
sequence$.subscribe(values => console.log("result observable " , values) );
}
?
请求异常处理
throwError() {
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..." )
);
}
当发生异常时,控制台的输出结果:
Error catched
HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/api/simulate-error", ok: false , … }
Value emitted successfully {description: "Error Value Emitted" }
HTTP Observable completed...
?
Http 拦截器
定义拦截器
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 { }
?
Http 进度事件
longRequest() {
const request = new HttpRequest(
"POST", "/api/test-request" , {},
{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);
}
}
);
}
上面示例运行后,控制台的可能的输出结果:
Upload progress event Object {type: 1, loaded: 2, total: 2 }
Download progress event Object {type: 3, loaded: 31, total: 31 }
Response Received... Object {description: "POST Response"}
?
?
?
转载自:
Angular HTTP Client 快速入门
?
?
?
?
查看更多关于Angular学习笔记—HttpClient (转载)的详细内容...