升级角度项目后出现此错误
this.http.post(...)。map(...)。concatMap不是函数
这是导致错误的代码
return this.http.post(apiURL, body, options)
.map(response => response.json())
.concatMap(response => {
// Check if the API_TOKEN is expired.
if (response.error.code == APIErrorCode.API_TOKEN_EXPIRED || response.error.code == 499) {
// Expired! Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
console.log("API_TOKEN expired.");
return this.requestAPIToken().delay(500)
.concatMap(response => this.doPost(api, body, attempts + 1));
}
console.log("API_TOKEN expired, request attempt limit reached!");
}
return Observable.of(response);
})
.catch((err, caught) => {
// Check if the session authentication token is expired.
if (authToken && err.status == 403) {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == APIErrorCode.SESSION_AUTH_TOKEN_EXPIRED) {
// Login session expired!
return Observable.of(response);
}
} catch (e) { }
}
// Check incidental bad request.
if (err.status == 400 && err.statusText == "Bad Request") {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == 400 && response.error.message
&& [ "access denied", "bad" ].includes(response.error.message.toLowerCase())) {
// Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
return this.requestAPIToken().delay(100)
.concatMap(response => this.doPost(api, body, attempts + 1));
}
console.log("Bad Request, request attempt limit reached!");
}
} catch (e) { }
}
return Observable.throw(err);
});
在升级我的角度项目之前,它工作正常,我不知道该怎么办
答案 0 :(得分:4)
如果刚升级了angular,则可能正在使用RxJS v6。如果是这样,则需要重构以使用管道运算符
还请注意,您应该使用HttpClient
而不是Http
,因为现在已经过时了。然后,您也可以使用response.json()
删除第一张地图,因为HttpClient
会自动为您完成。
请记住,您需要重构代码中的所有可观察变量,不仅是HttpClient
中的可观察变量,还应该重构具有delay
运算符的变量。
在这里查看更多信息:
https://rxjs-dev.firebaseapp.com/guide/v6/migration
import { of, throwError } from 'rxjs';
import { concatMap, catchError, delay } from 'rxjs/operators';
return this.httpClient.post(apiURL, body, options)
.pipe(
concatMap(response => {
// Check if the API_TOKEN is expired.
if (response.error.code == APIErrorCode.API_TOKEN_EXPIRED || response.error.code == 499) {
// Expired! Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
console.log("API_TOKEN expired.");
return this.requestAPIToken().pipe(
delay(500),
concatMap(response => this.doPost(api, body, attempts + 1)
);
}
console.log("API_TOKEN expired, request attempt limit reached!");
}
return of(response);
}),
catchError((err, caught) => {
// Check if the session authentication token is expired.
if (authToken && err.status == 403) {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == APIErrorCode.SESSION_AUTH_TOKEN_EXPIRED) {
// Login session expired!
return of(response);
}
} catch (e) { }
}
// Check incidental bad request.
if (err.status == 400 && err.statusText == "Bad Request") {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == 400 && response.error.message
&& [ "access denied", "bad" ].includes(response.error.message.toLowerCase())) {
// Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
return this.requestAPIToken().pipe(
delay(100),
concatMap(response => this.doPost(api, body, attempts + 1)
);
}
console.log("Bad Request, request attempt limit reached!");
}
} catch (e) { }
}
return throwError(err);
})
);
如果您使用的是v5.5,那么我的回答也应该有所帮助,但是您的问题是准确地缺少了concatMap
运算符导入。重构为可管道运算符,或仅添加import 'rxjs/add/operator/concatMap';
此导入将使用Observable
运算符猴子修补concatMap
对象-默认情况下不存在。
有关在RxJS v5中导入运算符的更多信息:
答案 1 :(得分:1)
扩展@MartinAdámek的答案:- 应该是这样的
return this.http.post(apiURL, body, options).pipe(
map(response => response.json()),
concatMap(response => {
//REST OF THE CODE
return of(response);
}))
此外,您无需编写 Observable.of(响应),现在您只需编写 of(响应) 这也适用于 Observable.throw()
答案 2 :(得分:0)
您可能正在使用RxJS。如果要合并map, filter, reduce
等...,请使用.pipe()
return this.http.post(...).pipe(
map(...).reduce(...)
}))
这样,您可以组合多种方法。