• Angular学习笔记—HttpClient (转载)


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

     
     
     
     
     
     
  • 相关阅读:
    单元测试之NUnit
    “Oracle.DataAccess.Client.OracleConnection”的类型初始值设定项引发异常
    功能强大的树状结构TreeGrid
    右键效果图
    可视化定义工作流(正在努力做......w)
    关于自动发送邮件换行等问题解决
    清空Cache
    .net发生类型为 System.OutOfMemoryException 的异常解决办法
    再谈xml
    Delphi日期函数大全
  • 原文地址:https://www.cnblogs.com/Jason-Xiang/p/9262931.html
Copyright © 2020-2023  润新知