前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Angular 6 HttpClient 快速入门

Angular 6 HttpClient 快速入门

作者头像
阿宝哥
发布2019-11-05 16:10:34
5K0
发布2019-11-05 16:10:34
举报
文章被收录于专栏:全栈修仙之路

本教程将介绍如何在 Angular 6.x 中使用 HttpClient 发送 Http 请求,如 get、post、put 和 delete 请求。在 Angular 4.3+ 版本之后引入了 HttpClientModule 模块,该模块提供的 HttpClient 服务是已有 Angular HTTP API 的演进,它在一个单独的 @angular/common/http 包中。

废话不多说,现在让我们来看一下如何在 Angular 6.x 中使用 HttpClientModule 模块。

导入 HttpClientModule 模块

代码语言:javascript
复制
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";

import { AppComponent } from "./app.component";

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

需要注意的是,现在 JSON 是默认的数据格式,我们不需要再进行显式的解析。即我们不需要再使用以下代码:

代码语言:javascript
复制
http.get(url).map(res => res.json()).subscribe(...)

现在我们可以这样写:

代码语言:javascript
复制
http.get(url).subscribe(...)

发送 Get 请求

代码语言:javascript
复制
import { Component, OnInit } from "@angular/core";
import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http";

import { Observable } from "rxjs";
import { tap } from "rxjs/operators";

interface Todo {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

@Component({
  selector: "app-root",
  template: `
    <ul *ngIf="todos$ | async as todos else noData">
        <li *ngFor="let todo of todos">
            <span>Title: {{todo.title}}</span> —— 
            <span>Completed: {{todo.completed}}</span>
        </li> 
    </ul>
    <ng-template #noData>No Data Available</ng-template>
`
})
export class AppComponent implements OnInit {
  todos$: Observable<Todo[]>;
  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.todos$ = this.http
      .get<Todo[]>(
        "https://jsonplaceholder.typicode.com/todos?_page=1&_limit=10"
      )
      .pipe(tap(console.log));
  }
}

设置查询参数

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

代码语言:javascript
复制
https://jsonplaceholder.typicode.com/todos?_page=1&_limit=10
创建 HttpParams 对象
代码语言:javascript
复制
import { HttpClient, HttpParams } from "@angular/common/http";

const params = new HttpParams().set("_page", "1").set("_limit", "10");

ngOnInit() {
  this.todos$ = this.http
    .get<Todo[]>("https://jsonplaceholder.typicode.com/todos", { params })
    .pipe(tap(console.log));
}

需要注意的是,我们通过链式语法调用 set() 方法,构建 HttpParams 对象。这是因为 HttpParams 对象是不可变的,通过 set() 方法可以防止该对象被修改。

每当调用 set() 方法,将会返回包含新值的 HttpParams 对象,因此如果使用下面的方式,将不能正确的设置参数。

代码语言:javascript
复制
const params = new HttpParams();

params.set("_page", "1")
params.set("_limit", "10");
使用 fromString
代码语言:javascript
复制
const params = new HttpParams({fromString: "_page=1&_limit=10"});
使用 fromObject
代码语言:javascript
复制
const params = new HttpParams({ fromObject: { _page: "1", _limit: "10" } });
使用 request API
代码语言:javascript
复制
ngOnInit() {
  this.users$ = this.http
    .request("GET", "https://jsonplaceholder.typicode.com/todos", { params })
    .pipe(tap(console.log));
}

获取完整响应

默认情况下,HttpClient 服务返回的是响应体,有时候我们需要获取响应头的相关信息,这时你可以设置请求 options 对象的 observe 属性值为 response 来获取完整的响应对象。

代码语言:javascript
复制
this.http.get("https://jsonplaceholder.typicode.com/todos/1", {
  observe: "response"
})
.subscribe(res => {
   console.dir("Response: " + res.status);
});

设置响应类型

如果你期望的响应对象的格式不是 JSON,你可以通过 responseType 属性来设定响应类型,比如:

代码语言:javascript
复制
this.http.get("https://jsonplaceholder.typicode.com/todos/1", {
  responseType: "text"
}).subscribe(text => {
   console.log("Response: " + text);
});

需要注意的是除了支持 json 和 text 类型外,还支持 arraybuffer 和 blob 类型。

设置 Http Headers

代码语言:javascript
复制
const params = new HttpParams({ fromObject: { _page: "1", _limit: "10" } });
const headers = new HttpHeaders().set("token", "iloveangular");

ngOnInit() {
  this.todos$ = this.http
    .get<Todo[]>("https://jsonplaceholder.typicode.com/todos", {
        headers,
        params
     })
     .pipe(tap(console.log));
 }

发送 Put 请求

代码语言:javascript
复制
const headers = new HttpHeaders().set(
  "Content-type",
  "application/json; charset=UTF-8"
);

updateFirstTodo() {
    this.http
      .put(
        "https://jsonplaceholder.typicode.com/todos/1",
        {
          userId: 1,
          id: 1,
          title: "delectus aut autem",
          completed: true
        },
        { headers }
      )
      .subscribe(
        val => {
          console.log("Put call successful value returned in body", val);
        },
        error => {
          console.log("Put call in error", error);
        },
        () => {
          console.log("The PUT observable is now completed.");
        }
      );
}

发送 Patch 请求

代码语言:javascript
复制
const headers = new HttpHeaders().set(
  "Content-type",
  "application/json; charset=UTF-8"
);

patchFirstTodo() {
    this.http
      .patch(
        "https://jsonplaceholder.typicode.com/todos/1",
        {
          title: "learn angular 7"
        },
        { headers }
      )
      .subscribe(
        val => {
          console.log("Patch call successful value returned in body", val);
        },
        error => {
          console.log("Patch call in error", error);
        },
        () => {
          console.log("The Patch observable is now completed.");
        }
      );
}

发送 Delete 请求

代码语言:javascript
复制
const headers = new HttpHeaders().set(
  "Content-type",
  "application/json; charset=UTF-8"
);

deleteFirstTodo() {
    this.http
      .delete("https://jsonplaceholder.typicode.com/todos/1", {
        headers
      })
      .subscribe(
        val => {
          console.log("Delete call successful value returned in body", val);
        },
        error => {
          console.log("Delete call in error", error);
        },
        () => {
          console.log("The Delete observable is now completed.");
        }
      );
}

发送 Post 请求

代码语言:javascript
复制
const headers = new HttpHeaders().set(
  "Content-type",
  "application/json; charset=UTF-8"
);

createNewTodo() {
    this.http
      .post(
        "https://jsonplaceholder.typicode.com/todos",
        {
          userId: 1,
          title: "learn ionic 4",
          completed: false
        },
        { headers }
      )
      .subscribe(
        val => {
          console.log("Post call successful value returned in body", val);
        },
        error => {
          console.log("Post call in error", error);
        },
        () => {
          console.log("The Post observable is now completed.");
        }
      );
  }

并行发送多个 Http 请求

代码语言:javascript
复制
parallelRequests() {
    const parallel$ = forkJoin(
      this.http.get("https://jsonplaceholder.typicode.com/users/1"),
      this.http.get("https://jsonplaceholder.typicode.com/todos/1")
    );

    parallel$.subscribe(values => {
      console.log("all values", values);
    });
 }

顺序发送 Http 请求

代码语言:javascript
复制
sequentialRequests() {
    const sequence$ = this.http
      .get<Todo>("https://jsonplaceholder.typicode.com/todos/1")
      .pipe(
        switchMap(todo => {
          todo.title += " - TEST ";
          return this.http.put("https://jsonplaceholder.typicode.com/todos/1", todo);
        })
      );

    sequence$.subscribe(val => {
      console.log("Put call successful value returned in body", val);
    });
}

获取顺序发送 Http 请求的结果

代码语言:javascript
复制
sequentialRequests() {
    const sequence$ = this.http
      .get<Todo>("https://jsonplaceholder.typicode.com/todos/1")
      .pipe(
        switchMap(
          todo => {
            const newTitle = todo.title + " - TEST ";
            const newTodo = { ...todo, title: newTitle };
            return this.http.put(
              "https://jsonplaceholder.typicode.com/todos/1",
              newTodo
            );
          },
          (firstHTTPResult, secondHTTPResult) => [
            firstHTTPResult,
            secondHTTPResult
          ]
        )
      );

    sequence$.subscribe(val => {
      console.log("Put call successful value returned in body", val);
    });
}

请求异常处理

代码语言:javascript
复制
import { of } from "rxjs";
import { catchError } from "rxjs/operators";

throwError() {
    this.http
      .get("https://jsonplaceholder.typicode.com/simulate-error")
      .pipe(
        catchError(error => {
          console.error("Error catched", error);
          return 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...")
      );
}

当发生异常时,控制台的输出结果:

代码语言:javascript
复制
Error catched 
HttpErrorResponse {headers: HttpHeaders, status: 404, ...}
Value emitted successfully {description: "Error Value Emitted"}
HTTP Observable completed...

Http 拦截器

定义拦截器

auth.interceptor.ts

代码语言:javascript
复制
import { Injectable } from "@angular/core";
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor } from "@angular/common/http";

import { Observable } from "rxjs";

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const clonedRequest = req.clone({
      headers: req.headers.set("X-CustomAuthHeader", "iloveangular")
    });
    console.log("new headers", clonedRequest.headers.keys());
    return next.handle(clonedRequest);
  }
}
应用拦截器
代码语言:javascript
复制
import { AuthInterceptor } from "./interceptors/auth.interceptor";

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Http 进度事件

代码语言:javascript
复制
getData() {
   this.http
      .get("https://jsonplaceholder.typicode.com/todos", {
        observe: 'events',
        reportProgress: true
      })
      .subscribe((event: HttpEvent<any>) => {
        switch (event.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(event.loaded / 1024);
            console.log(`Download in progress! ${kbLoaded}Kb loaded`);
            break;
          case HttpEventType.Response:
            console.log("Done!", event.body);
        }
      });
}

以上代码成功运行后,在控制台会输出以下信息:

代码语言:javascript
复制
Request sent!
Response header received!
Download in progress! 6Kb loaded
Download in progress! 24Kb loaded
Done!

总结

本文通过 jsonplaceholder 提供的 API,介绍了如何使用 HttpClientModule 模块中的 HttpClient 服务,发送 Get、Post、Delete 等请求,同时介绍了如何利用 RxJS 处理并行和顺序 Http 请求。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/08/27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导入 HttpClientModule 模块
  • 发送 Get 请求
  • 设置查询参数
    • 创建 HttpParams 对象
      • 使用 fromString
        • 使用 fromObject
          • 使用 request API
          • 获取完整响应
          • 设置响应类型
          • 设置 Http Headers
          • 发送 Put 请求
          • 发送 Patch 请求
          • 发送 Delete 请求
          • 发送 Post 请求
          • 并行发送多个 Http 请求
          • 顺序发送 Http 请求
          • 获取顺序发送 Http 请求的结果
          • 请求异常处理
          • Http 拦截器
            • 定义拦截器
              • 应用拦截器
              • Http 进度事件
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档