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.com/courses.json")
.map(data => _.values(data))
.do(console.log);
}
}

设置查询参数

假设发送 Get 请求时,需要设置对应的查询参数,预期的 URL 地址如下:

https://angular-http-guide.firebaseio.com/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 (转载)的更多相关文章

  1. angular学习笔记(三十一)-$location(2)

    之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...

  2. angular学习笔记(三十一)-$location(1)

    本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...

  3. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  4. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

  5. angular学习笔记(三十)-指令(7)-compile和link(1)

    这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...

  6. angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

  7. angular学习笔记(三十)-指令(5)-link

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

  8. angular学习笔记(三十)-指令(2)-restrice,replace,template

    本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...

  9. angular学习笔记(三十)-指令(1)-概述

    之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('dir ...

随机推荐

  1. Action的mapping.findFoward(forwardName)必须要在struts-config.xml中的对应的action节点配置一个forward节点

    比如说你有个SampleAction,在execute(ActionMapping mapping, ...)中写了句 return mapping.findForward("some_pa ...

  2. async and await 简单的入门

    如果有几个Uri,需要获取这些Uri的所有内容的长度之和,你会如何做? 很简单,使用WebClient一个一个的获取uri的内容长度,进行累加. 也就是说如果有5个Uri,请求的时间分别是:1s 2s ...

  3. Unix系统编程(一)

    主要内容:文件输入/输出的系统调用. 在Linux中,万事万物皆文件. 文件描述符的概念 通用I/O模型的系统调用: 打开文件 open 关闭文件 close 向文件写数据 write 从文件读数据 ...

  4. Unknown module(s) in QT: xlsx解决方法

    解决方法在此: https://github.com/dbzhang800/QtXlsxWriter Documentation: http://qtxlsx.debao.me QtXlsx is a ...

  5. PHP——上传文件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. www--摘录图解TCP/IP

    万维网,www,world wide web,也称web.将互联网中的信息以超文本的形式展现的系统.可以显示www信息的客户端软件叫做web浏览器. www内容 www定义了3个重要的概念,它们分别是 ...

  7. 中小企业项目的痛VS感人IT团队

    早上,接到客户电话,dynamics CRM不能用了,此客户从开始安装程序开始二次开发期间,因电源问题导致服务器多次意外断电,至今也不加UPS电源.前几次,都不是很严重,服务器没有大量文件损坏,操作系 ...

  8. expr判断整数是相加的值,返回命令的返回值$? 是0,但是少数情况是1,例如1 + -1 ,$? 的结果是1 ,判断要大于1最准确

    [root@m01 ~]# expr 1 + 12[root@m01 ~]# echo $?0[root@m01 ~]# echo 1 - 51 - 5[root@m01 ~]# expr 1 - 5 ...

  9. 浅谈SRAM与DRAM的异同

    在上体系结构这门课之前,我只知道DRAM用作内存比较多,SRAM用作cache比较多.在今天讲到内存技术时,我对于这两个基础概念有了更加完整的认识.这篇文章是我的听课心得,现在分享给各位,仅供参考,若 ...

  10. php 判断时间是否超过

    $str="2014-10-11"; echo "".strtotime($str); echo "<br/>"; echo & ...