好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

 

 

 

 

 

 

 

 

 

 

查看更多关于Angular学习笔记—HttpClient (转载)的详细内容...

  阅读:35次