Angular学习笔记—HttpClient (转载)

   2023-03-08 学习力0
核心提示:HttpClientModule 应用导入新的 HTTP Moduleimport {HttpClientModule} from '@angular/common/http';@NgModule({declarations: [AppComponent],imports: [BrowserModule,HttpClientModule],providers: [],bootstrap: [AppComponent]})export class AppModule

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 快速入门

 

 

 

 

 
 
 
 
 
 
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Angular.js的作用域和数据绑定
    初识Angular.js通过初识Angular.js可以做一个简单的入门,下面开始做深入的了解吧。作用域作用域($scope)和应用的数据模型相关联的,同时作用域也是表达式执行的上下文。$scope对象是定义应用业务逻辑、控制器方法和视图属性的地方。 作用域是视图和控制器
    03-16
  • Angular 4 设置组件样式的几种方式
    Angular 4 设置组件样式的几种方式
      你用Angular吗?一.介绍  如何只改动最简单的css代码,呈现完全不一样的视图效果。第一种:最基本的设置:  图1 代码 图2 界面运行效果图平常,想给一个label或者p等标签添加样式,我们就是这样操作,在Angular中也是一样的。现在,如果我想要将字体换
    03-16
  • angularJSapi学习-angular.copy使用
    angular.copy使用效果:初始状态:输入信息后未保存状态:点击save后状态:当输入框内容和master内容不一致时:点击reset使得user的信息被重置为master中信息: 具体代码: 1 !DOCTYPE HTML 2 html ng-app="app" 3 headscript src="./angular.min.js"/script
    03-16
  • Ionic启动时提示:The Angular CLI requires a minimum Node.js version of eithor v10.13 or v12.0
    Ionic启动时提示:The Angular CLI requires a m
    在新建ionic项目后通过ionic serve 启动ionic项目时提示:The Angular CLI requires a minimum Node.js version of eithor v10.13 or v12.0  注:博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号霸道的程序猿获取编程相关电子书、教程推送与
    03-16
  • Angular.js之内置过滤器学习笔记 javascript过
    !DOCTYPE htmlhtml lang="en"headmeta charset="UTF-8"titleangularFilter/titlescript src="http://cdn.bootcss.com/angular.js/1.4.6/angular.js"/script/head  body ng-app="angularJS" ng-controller="ctrl"    div{{
    03-08
  • Angular 隨記
    Windows下更新Node 和NPM方法管理員模式打開powershell執行以下命令:Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Forcenpm install -g npm-windows-upgradenpm-windows-upgrade
    03-08
  • 双向数据绑定(angular,vue) 双向数据绑定指令
    最近github上插件项目更新了关于双向数据绑定的实现方式,关于angular和vue.angular众所周知是使用的脏检查($dirty)。一开始大家会认为angular开启了类似setInterval去不停的循环检查,性能极差,但其实并不是,$dirty是在一定条件下才会去执行,比如输入框
    03-08
  • 六、angular 生成二维码
    六、angular 生成二维码
    首先需要安装angular-qrcode :bower install monospaced/angular-qrcodenpm install angular-qrcode如何使用?在相应的需要使用二维码的页面增加如下代码:注意:这里的“version”和"size"可以根据github上面找出自己想要的结果:生成含有图片的二维码:这里
    03-08
  • angular.js简单入门。 angular入门教程
    angular.js简单入门。 angular入门教程
    小弟刚接触angular js  就写了一个简单的入门。后续慢慢补。。。首先看 html 页面。htmlmeta charset="UTF-8"headtitleangularJS/title/headscript type="text/javascript" src="./js/angular.min.js"/script      //引入 angularJSscript type="text/
    03-08
点击排行