Angular HttpClient修改服务中的响应

时间:2017-12-03 09:44:54

标签: angular rxjs

我正在升级到Angular到版本5,之前我使用的是@angular/common/http,现在我需要更新到return this.http.get(url, {headers: this.headers}).map( (response: Response) => { const data = response.json(); // Does something on data.data // return the modified data: return data.data; } ).catch( (error: Response) => { return Observable.throw(error); } ); 并使用HttpClient

我已经在服务中(而不是在组件中)发出http请求,并且使它们易于重用

这是我已经拥有的(来自弃用的http)

HttpClient

现在从我从新{{1}}学到的东西,就像我无法修改响应并将其提供给订阅它的组件方法。

如何修改对HTTP请求的响应并在从Observable返回之前轻松访问它?

我只是想要同样的能力来修改我从API获得的响应...就像添加一些项目,或者在撤回它之前做更多的东西

6 个答案:

答案 0 :(得分:21)

这完全取决于RxJ的版本。 Angular 6附带RxJs 6 - 这意味着map()/ catch()方法不再有效。

相反,你必须使用pipe + map()/ catchError(),如下所示:

在Angular 6 / RxJs 6之前 - 经典的Http使用:

return this.http.get(url, {headers: this.headers}).map(
  (response: Response) => {
    const data : SomeType = response.json() as SomeType;
    // Does something on data.data

    // return the modified data:
    return data.data; // assuming SomeType has a data properties. Following OP post
  }
).catch(
  (error: Response) => {
    return Observable.throw(error);
  }
);

应改为:

Angular 6 / RxJs 6之后 - HttpClient迁移:

return this.http.get<SomeType>(url, {headers: this.headers})
  .pipe(
     map( response => {  // NOTE: response is of type SomeType
         // Does something on response.data
         // modify the response.data as you see fit.

         // return the modified data:
         return response; // kind of useless
     }),
     catchError( error => {
         return Observable.throw(error);
     })
  ); // end of pipe

在管道中,map()将获取响应对象(已经从Json解析),如果http失败,catchError()将获取第一个错误。

另外,请注意您的Headers也需要是HttpHeaders对象。

在RxJs 6中读取pipe,map和catchError

答案 1 :(得分:2)

我的服务

import {HttpClient} from '@angular/common/http';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class DataService {
    constructor(private http: HttpClient) {}
    getData()
    {
        return this.http.get('../assets/data.json').map(data=>{
            return this.process(data);
        }).catch(
            (error: Response) => {
              return Observable.throw(error);
            });
    }
    process(data:any)  
    {
        let dataTransform:any[]=[];
        let i:number=0;
        for (let item of data)
        {
            dataTransform.push({"id":i,"key":item.key});
            i++;
        }
        return dataTransform;
    }
}

//我的组件

export class AppComponent implements OnInit {
  constructor(private dataService:DataService){}
  ngOnInit(){
    this.dataService.getData().subscribe((data:any)=> {
      console.log(data);
    });
  }
}

// asset / data.json

[
    {"key":"uno"},
    {"key":"dos"},
    {"key":"tres"},
    {"key":"cuatro"},
    {"key":"cinco"}
]

答案 2 :(得分:1)

如果您想更有效地处理错误,请在下面编写代码和错误类别,请注意每个部分:

  1. 我创建了一个文件夹错误,并在此文件夹中为每个错误创建一个类,这些错误可能是500个错误或400个错误,如自爆图像:
  2. Error Classes

    1. 创建一个类 app-error.ts ,如下面的代码:

      export class AppError {
          constructor(public originalError?: any) { }
      }
      
    2. 另一个错误类从app-error.ts 类扩展:

      // not-found-error.ts class
      import {AppError} from './app-error';
      
      export class NotFoundError extends AppError { }
      
      
      
      // conflict-error.ts class
      import {AppError} from './app-error';
      
      export class ConflictError extends AppError { }
      
      
      
      // internal-server-error.ts class
      import {AppError} from './app-error';
      
      export class InternalServerError extends AppError { }
      
      
      
      // bad-request-error.ts class
      import {AppError} from './app-error';
      
      export class BadRequestError extends AppError {
          constructor(public originalError?: any) {
              super(originalError);
          }
      
          get errors(): string[] {
              if (this.originalError)
                  return this.originalError;
      
              return null;
          }
      }
      
    3. 如果您想访问基本错误或者您可以修改错误,我会在最新的课程 bad-request-error.ts

    4. 中进行修改
    5. 然后您可以使用这些类inisde服务:

      import {Injectable} from '@angular/core';
      import {HttpClient} from '@angular/common/http';
      import {HttpHeaders} from '@angular/common/http';
      
      import {Observable} from 'rxjs/Observable';
      import 'rxjs/add/operator/map';
      import 'rxjs/add/operator/catch';
      import 'rxjs/add/observable/throw';
      
      import {AppError} from '../errors/app-error';
      import {BadRequestError} from '../errors/bad-request-error';
      import {NotFoundError} from '../errors/not-found-error';
      import {InternalServerError} from '../errors/internal-server-error';
      import {ConflictError} from '../errors/conflict-error';
      
      @Injectable()
      export class DataService {
          public headers = new HttpHeaders().set('Content-Type', 'application/json');
      
          constructor(public http: HttpClient, public url: string) { }
      
          get(id: number) {
              return this.http.get(`${this.url}/${id}`, {headers: this.headers})
                     .map((response) => response.json())
                     .catch(DataService.handleError);
          }
      
          create(resource) {
              return this.http.post(this.url, JSON.stringify(resource), {headers: this.headers})
                     .map((response) => response.json())
                     .catch(DataService.handleError);
          }
      
          update(id: number, resource) {
              return this.http.put(`${this.url}/${id}`, JSON.stringify(resource), {headers: this.headers})
                     .map((response) => response.json())
                     .catch(DataService.handleError);
          }
      
          remove(id: number) {
              return this.http.delete(`${this.url}/${id}`, {headers: this.headers})
                     .map((response) => response.json())
                     .catch(DataService.handleError);
          }
      
          public static handleError(error: Response) {
              switch (error.status) {
                  case 400:
                      return Observable.throw(new BadRequestError(error));
                  case 404:
                      return Observable.throw(new NotFoundError());
                  case 409:
                      return Observable.throw(new ConflictError());
                  case 500:
                      return Observable.throw(new InternalServerError());
      
                  default:
                      return Observable.throw(new AppError(error));
              }
          }
      }
      
    6. 以上代码是错误处理和使用map运算符以成功方式处理响应的最佳代码

    7. 最新的步伐是在组件内使用服务,如下面的代码:

      import {Component} from '@angular/core';
      import {OnInit} from '@angular/core';
      import {HttpParams} from '@angular/common/http';
      
      import {DataService} from '../../services/data.service';
      
      import {AppError} from '../errors/app-error';
      import {BadRequestError} from '../errors/bad-request-error';
      import {NotFoundError} from '../errors/not-found-error';
      import {InternalServerError} from '../errors/internal-server-error';
      import {ConflictError} from '../errors/conflict-error';
      
      @Component({
          selector: 'app-data',
          templateUrl: './data.component.html',
          styleUrls: ['./data.component.css']
      })
      export class DataComponent implements OnInit {
      
          constructor(private dataService: DataService) {
          }
      
          ngOnInit() {
              this.dataService.get(123).subscribe(
                  (response: DataModel) => {
                      // ...
                  },
                  (error: AppError) => {
                      if (error instanceof NotFoundError) {
                          // ...
                      } else if (error instanceof BadRequestError) {
                          // ...
                      } else if (error instanceof ConflictError) {
                          // ...
                      } else {
                          // ...
                      }
                  }
              );
          }
      }
      

答案 3 :(得分:1)

您可以创建自己的Observable来包装http.get并返回被操纵的响应,在本例中它是manipulatedAccountsResponse对象:

{{1}}

}

答案 4 :(得分:0)

根据我的考虑,您可以在成功响应中调用该服务的功能,并在功能中处理您的数据并将其返回给它。

return this.http.get(url, {headers: this.headers}).map(
      (response: Response) => {
        const data = response.json();
        return this.processData(data);
      }
    ).catch(
      (error: Response) => {
        return Observable.throw(error);
      }
    );
    
public processData(data : any){
  //process your data
  return data;//this is processed data
}

答案 5 :(得分:0)

在“新”Httpclient中,默认情况下返回json响应。然后你只写

import {HttpClient} from '@angular/common/http'; //<--HttpClient
import 'rxjs/add/operator/map';                  //import the operator "map"
import 'rxjs/add/operator/catch'; //and the operator "catch"

....
constructor(private http: HttpClient) {} //<--sure HttpClient
...
return this.http.get(url).map(  //yet get "data"
      (data:any) => {
        return this.processData(data);
      }
    ).catch(
      (error: Response) => {
        return Observable.throw(error);
      }
    );

public processData(data : any){
  //process your data
  return data;//this is processed data
}