我正在升级到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获得的响应...就像添加一些项目,或者在撤回它之前做更多的东西
答案 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)
如果您想更有效地处理错误,请在下面编写代码和错误类别,请注意每个部分:
创建一个类 app-error.ts ,如下面的代码:
export class AppError {
constructor(public originalError?: any) { }
}
另一个错误类从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;
}
}
如果您想访问基本错误或者您可以修改错误,我会在最新的课程 bad-request-error.ts
然后您可以使用这些类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));
}
}
}
以上代码是错误处理和使用map运算符以成功方式处理响应的最佳代码。
最新的步伐是在组件内使用服务,如下面的代码:
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
}