首页 > 解决方案 > 如何解决这个问题(“this.http.post(...).map(...).concatMap 不是函数”)?

问题描述

升级我的角度项目后出现此错误

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);
        });

在我升级我的角度项目之前它工作正常,我不知道现在该怎么做

标签: angular

解决方案


如果你刚刚升级了 Angular,你可能正在使用 RxJS v6。如果是这样,您需要重构以使用可管道操作符

另请注意,您应该使用它,HttpClient而不是Http现在已弃用很长时间。然后您也可以使用 删除第一张地图response.json(),就像HttpClient自动为您所做的那样。

请记住,您需要重构代码中的所有可观察对象,不仅是 from 的HttpClient那个,还包括带有delayoperator 的那些。

在这里查看更多信息:

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 中导入操作符的信息:

https://www.learnrxjs.io/concepts/operator-imports.html


推荐阅读