【问题标题】:Ionic 3 - Type '{}' is not assignable to typeIonic 3 - 类型“{}”不可分配给类型
【发布时间】:2018-09-30 10:14:41
【问题描述】:

试图找出这个错误。我正在尝试调用 API,并将 API 调用中的 JSON 数据映射到 CurrencyModel。没有问题,但是当我调用一个返回 observable 的方法时(因为它正在等待其他两个 API 调用),它会向提供者属性抛出以下错误:

类型“{}”不可分配给类型“CurrencyModel”。

src/models/currency.ts

export class CurrencyModel{
    private _base_currency_code: string;
    private _base_currency_symbol: string;
    private _default_display_currency_code: string;
    private _default_display_currency_symbol: string;
    private _available_currency_codes: Array<string> = [];
    private _exchange_rates: Array<CurrencyExchangeRateModel> = [];
    //extension attributes

    get base_currency_code(): string{
        return this._base_currency_code;
    }

    set base_currency_code(value: string){
        this._base_currency_code = value;
    }

    get base_currency_symbol(): string{
        return this._base_currency_symbol;
    }

    set base_currency_symbol(value: string){
        this._base_currency_symbol = value;
    }

    get default_display_currency_code(): string{
        return this._default_display_currency_code;
    }

    set default_display_currency_code(value: string){
        this._default_display_currency_code = value;
    }

    get default_display_currency_symbol(): string{
        return this._default_display_currency_symbol;
    }

    set default_display_currency_symbol(value: string){
        this._default_display_currency_symbol = value;
    }

    get available_currency_codes(): Array<string>{
        return this._available_currency_codes;
    }

    getAvailableCurrencyCode(key: number): string{
        return this.available_currency_codes[key];
    }

    set available_currency_codes(value: Array<string>){
        this._available_currency_codes = value;
    }

    setAvailableCurrencyCode(value: string): void{
        this.available_currency_codes.push(value);
   }

    get exchange_rates(): Array<CurrencyExchangeRateModel>{
        return this._exchange_rates;
    }

    getExchangeRate(key: number): CurrencyExchangeRateModel{
        return this.exchange_rates[key];
    }

    set exchange_rates(value: Array<CurrencyExchangeRateModel>){
        this._exchange_rates = value;
    }

    setExchangeRate(value: CurrencyExchangeRateModel): void{
        this.exchange_rates.push(value);
    }

    constructor(response?: any){
        if(response){
            this.base_currency_code = response.base_currency_code;
            this.base_currency_symbol = response.base_currency_symbol;
            this.default_display_currency_code = response.default_display_currency_code;
            this.default_display_currency_symbol = response.default_display_currency_symbol;
            this.available_currency_codes = response.available_currency_codes ;

            if(response.exchange_rates){
                for(let rate of response.exchange_rates){
                    this.setExchangeRate( new CurrencyExchangeRateModel(rate) );
                }
            }
        }
    }
}

src/providers/store/store.ts

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Platform } from 'ionic-angular';

import { CurrencyModel } from '../../models/store/currency';

import { Observable } from 'rxjs/Observable';
import { forkJoin } from "rxjs/observable/forkJoin";
import { map } from 'rxjs/operators';

@Injectable()

export class StoreProvider {
    private apiUrl:string;

    // Defaults
    config: ConfigModel;
    countries: Array<CountryModel> = [];
    currency: CurrencyModel;

    constructor(public http: HttpClient){}

    readCurrency(): Observable<CurrencyModel>{
        return this.http.get<CurrencyModel>(this.apiUrl + '/directory/currency').pipe(
            map(data => new CurrencyModel(data))
        );
    }

    readConfig(): any{
        return this.http.get(this.apiUrl + '/store/storeConfigs');
    }

    //readCountries is the same, just different url

    getProperties(): Observable<boolean>{
        return Observable.create(observer => {
            let requests: Array<any> = [
                this.readConfig(),
                this.readCountries(),
                this.readCurrency()
            ];

            forkJoin(requests).subscribe(data => {

                this.config = this.getConfig(data[0][0]);
                this.countries = this.getCountries(data[1]);
                this.currency = data[2]; // Problem area

                observer.next(true);
            }, err => {
                observer.error(err);
            });
        });
    }
}

getProperties 的目的是从网站获取需要先加载的数据。

响应的数据结构(Magento 2 Currency)

{
    "base_currency_code": "string",
    "base_currency_symbol": "string",
    "default_display_currency_code": "string",
    "default_display_currency_symbol": "string",
    "available_currency_codes": [
        "string"
    ],
    "exchange_rates": [
        {
            "currency_to": "string",
            "rate": 0,
            "extension_attributes": {}
        }
    ],
    "extension_attributes": {}
}

编辑:添加 JSON 数据结构和 CurrencyModel

【问题讨论】:

  • 如果错误是在编译时,试试this.currency = data[2] as CurrencyModel;

标签: angular rest typescript rxjs ionic3


【解决方案1】:

这是因为当你订阅forkJoin时,你收到的数据类型编译器并不清楚

你可以试试这个

this.currency = data[2] as CurrencyModel;

甚至这个

forkJoin(requests).subscribe((data: any[]) => {
 //your code...

【讨论】:

  • 我从来没有意识到你可以这样使用别名,而且它奏效了。谢谢!
【解决方案2】:

这只是打字稿抱怨变量 data 的类型。指定类型将解决问题。

   forkJoin(requests).subscribe((data: CurrencyModel[]) => {

                    this.config = this.getConfig(data[0][0]);
                    this.countries = this.getCountries(data[1]);
                    this.currency = data[2]; // Problem area

                    observer.next(true);
                }

【讨论】:

  • 数据数组不只是 CurrencyModel,而是不同的模型,但确实有意义。
猜你喜欢
  • 1970-01-01
  • 2018-06-27
  • 2020-05-28
  • 2021-06-07
  • 2020-04-02
  • 2019-06-02
  • 1970-01-01
  • 2018-01-04
  • 2020-11-09
相关资源
最近更新 更多