【问题标题】:Upgrading from Ionic 3 to 5 - .map no longer works on observables从 Ionic 3 升级到 5 - .map 不再适用于可观察对象
【发布时间】:2021-06-05 16:43:45
【问题描述】:

当错误状态:属性“地图”不存在于类型“可观察”时,我将如何将 Ionic 3 中的此代码更改为 Ionic 5 升级。

return XApi.addTransaction('clicksActive', parameters, 
   { timeout: AppConfig.OTP_REQUEST_TIMEOUT, queue: false })
.map(res => {
        let response = res.data;
        let clicksActive: ClicksActive = this.parseActiveResponse(response);
        return clicksActive;
    }).catch(error => {
        let errorMessage = getLambdaErrorMessage(error);
        let clicksActive: ClicksActive = {
            success: false,
            active: false,
            errorMessage: errorMessage
        }
        return Observable.of(clicksActive);
    });

我尝试将其更改为:

return XApi.addTransaction('clicksActive', parameters, 
{ timeout: AppConfig.OTP_REQUEST_TIMEOUT, queue: false })
.pipe(map(res => {
        let response = res.data;
        let clicksActive: ClicksActive = this.parseActiveResponse(response);
        return clicksActive;
    })).catch(error => {
        let errorMessage = getLambdaErrorMessage(error);
        let clicksActive: ClicksActive = {
            success: false,
            active: false,
            errorMessage: errorMessage
        }

        return Observable.of(clicksActive);
    });

然后我得到错误: “OperatorFunction”类型的参数不可分配给“UnaryFunction”类型的参数。 参数 'source' 和 'source' 的类型不兼容。 “Observable”类型缺少“Observable”类型的以下属性:buffer、bufferCount、bufferTime、bufferToggle 和 104

更新: 这是我对整个 service.ts 的更新代码:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx'
import { AppConfig } from '../config/app-config';
import { XApi  } from 'x-lib';

import { ClicksActive, ClicksBalance } from '../models/user.model';
import { getLambdaErrorMessage } from "../helpers/lambda-error.helper";
import { map } from 'rxjs/operators';
import { catchError } from 'rxjs/operators';


@Injectable()
export class ClicksService {

    constructor() {
    }

    requestActive(
        idNumber: String
    ): Observable<ClicksActive> {

        let parameters =
        {
            apiUsername: this.getApiUsername(),
            apiPassword: this.getApiPassword(),
            apiBaseUrl: this.getApiBaseUrl(),
            idNumber: idNumber
        }

        return XApi.addTransaction('clicksActive', parameters, { timeout: AppConfig.OTP_REQUEST_TIMEOUT, queue: false })
        .pipe(
            map((res) => {
            let response = res.data;
            let clicksActive: ClicksActive = this.parseActiveResponse(response);
            return clicksActive;
        }), catchError((error) => {
            let errorMessage = getLambdaErrorMessage(error);
            let clicksActive: ClicksActive = {
                success: false,
                active: false,
                errorMessage: errorMessage
            }

            return Observable.of(clicksActive);
        })
        );
    }
   




      
    parseActiveResponse(response): ClicksActive {
        let clicksActive: ClicksActive = {
            success: response.success,
            active: response.active,
            errorMessage: response.errorMessage
        }
        return clicksActive;
    }

    requestBalance(
        idNumber: String
    ): Observable<ClicksBalance> {

        let parameters =
        {
            apiUsername: this.getApiUsername(),
            apiPassword: this.getApiPassword(),
            apiBaseUrl: this.getApiBaseUrl(),
            idNumber: idNumber
        }

        /*let clicksBalance: ClicksBalance = {
            success: true,
            balance :{
              cardNumber: '123456789',
              amount: 110,
              limit: 220,
              timestamp: Date()
            },
            errorMessage: ""
        };

        return Observable.of(clicksBalance);*/
        return XApi.addTransaction('clicksBalance', parameters, { timeout: AppConfig.OTP_REQUEST_TIMEOUT, queue: false }).map(res => {
            let response = res.data;
            let clicksBalance: ClicksBalance = this.parseBalanceResponse(response);
            return clicksBalance;
        }).catch(error => {
            let errorMessage = getLambdaErrorMessage(error);
            let clicksBalance: ClicksBalance = {
                success: false,
                balance :{
                  cardNumber: '',
                  amount: 0,
                  limit: 0,
                  timestamp: null
                },
                errorMessage: errorMessage
            };

            return Observable.of(clicksBalance);
        });
    }

    /* GENERIC SERVICES */
    getApiUsername(): String {
        if (AppConfig.ENVIRONMENT == 'dev') {
            return AppConfig.DEV_API_USERNAME;
        }
        else if (AppConfig.ENVIRONMENT == 'qas') {
            return AppConfig.QAS_API_USERNAME;
        }
        else if (AppConfig.ENVIRONMENT == 'prd') {
            return AppConfig.PRD_API_USERNAME;
        }
    }

    getApiPassword(): String {
        if (AppConfig.ENVIRONMENT == 'dev') {
            return AppConfig.DEV_API_PASSWORD;
        }
        else if (AppConfig.ENVIRONMENT == 'qas') {
            return AppConfig.QAS_API_PASSWORD;
        }
        else if (AppConfig.ENVIRONMENT == 'prd') {
            return AppConfig.PRD_API_PASSWORD;
        }
    }

    getApiBaseUrl(): String {
        if (AppConfig.ENVIRONMENT == 'dev') {
            return AppConfig.DEV_API_BASE_URL;
        }
        else if (AppConfig.ENVIRONMENT == 'qas') {
            return AppConfig.QAS_API_BASE_URL;
        }
        else if (AppConfig.ENVIRONMENT == 'prd') {
            return AppConfig.PRD_API_BASE_URL;
        }
    }

    parseBalanceResponse(response): ClicksBalance {
        if(response.success){
            let clicksBalance: ClicksBalance = {
                success: response.success,
                balance :{
                  cardNumber: response.balance.cardNumber,
                  amount: response.balance.amount,
                  limit: response.balance.limit,
                  timestamp: response.balance.timestamp
                },
                errorMessage: response.errorMessage
            }
            return clicksBalance;
        }
        else{
            let clicksBalance: ClicksBalance = {
                success: response.success,
                balance : response.balance,
                errorMessage: response.errorMessage
            }
            return clicksBalance;
        }
        
    }
}

【问题讨论】:

  • 您能否添加更多有关错误发生位置的详细信息?哪一行或什么方法会抛出这个错误?
  • 您好,我已经更新了我的问题以包含更多完整的 clicks.service.ts 代码。您会看到我在第一个实例中使用了 pipe(),但它不起作用 - 错误是“OperatorFunction”类型的参数不可分配给“UnaryFunction, Observable”类型的参数>'。参数 'source' 和 'source' 的类型不兼容。 “Observable”类型缺少“Observable”类型的以下属性:buffer、bufferCount、bufferTime、bufferToggle 等 104 个。
  • 根据我更新的代码@E.Maggini 有什么想法吗?

标签: angular ionic-framework rxjs


【解决方案1】:

您正在使用新的 Rxjs 和 Ionic 5,因此您需要使用管道函数和新的运算符。这是此迁移的指南:https://ionicframework.com/docs/reference/migration

但是,为了解决您的问题,您需要以这种方式调用 map 和 catchError 运算符:

  call(): Observable<{}>{
    return this.addTransaction() // <- simulate the observable which add a transaction
      .pipe(
        map((res) => {
          // your logic here on success
          // ...

          return {};  // I am using {} but you need to apply your payload
        }),
        catchError((error) => {
          // your logic here on error
          // ...

          return of({}); // I am using {} but you need to apply your payload
        })
      );
  }

  addTransaction(): Observable<{}>{
    return of({}); // I am using {} but you need to apply your payload
  }

【讨论】:

  • 谢谢您-我已经更新了我的问题以包含更多代码-您首先会看到我尝试使用您的 pipe() 建议,但我仍然遇到与根据我的问题。
  • 根据我更新的代码@bjdose 有什么想法吗?
  • 你只需要从 rxjs 导入 Observable,所以尝试使用 import { Observable } from 'rxjs' 而不是 import { Observable } from 'rxjs/Rx';
  • 嗨@bjdose,我导入 Observable 的方式没有任何区别。还有其他想法吗?
猜你喜欢
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多