skip to Main Content

Trying to figure out this error. I am attempting to call on an API, and map the JSON data from the API call to a CurrencyModel. No issues with that, but when I am calling on a method that returns an observable (as it is waiting for two other API calls), it’s throwing the following error to the provider property:

Type ‘{}’ is not assignable to type ‘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);
            });
        });
    }
}

Purpose with the getProperties is to get data from the website that will need to be loaded first before anything else.

Data structure of response (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": {}
}

EDIT: Added the JSON data structure and CurrencyModel

2

Answers


  1. It’s just typescript complaining about the type of the variable data . Specifying the type would solve the problem.

       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);
                    }
    
    Login or Signup to reply.
  2. This is because when you subscribe to forkJoin, the type of data you receive is unclear to the the compiler

    You can try this

    this.currency = data[2] as CurrencyModel;
    

    Or even this

    forkJoin(requests).subscribe((data: any[]) => {
     //your code...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search