-2

I am trying to create a custom pipe to access the data from JSON file and use the data in ts file. I have a issue on how to access the data outside a function.

@Pipe({ name: 'currency' })
export class CurrencyPipe implements PipeTransform {
  constructor(private httpService: HttpClient) { }
  arrCurrencies: any;
  transform(value, country): string {
    if (!value) {
      return ''
    } else {
      if (!country) {
        country = 'NZD'
      }
      const symbol = symbols[country] //value of symbol is $
      if (symbol) {
        this.httpService.get('./assets/locales/en_AU.json').subscribe(
          data => {
            this.arrCurrencies = data;
          });
           console.log('this.arrCurrencies', this.arrCurrencies); // not able to access arrCurrencies outside the func.
            return accounting.formatMoney(value, { symbol, format: '%s %v',precision : this.arrCurrencies.CURRENCYFORMATS.AUD.CURRENCYDECIMALS , thousand: ",",
            decimal : "." })
      }
      return accounting.formatMoney(value, { symbol: country, format: '%v %s' })
    }
  }
}

JSON:

"CURRENCYFORMATS": {
    "DEFAULT": {
        "DECIMALSEPARATOR": ".",
        "THOUSANDSEPARATOR": ",",
        "CURRENCYDECIMALS": "2"
    },
    "AUD": {
        "DECIMALSEPARATOR": ".",
        "THOUSANDSEPARATOR": ",",
        "CURRENCYDECIMALS": "4"
    },
}
angie
  • 13
  • 1
  • 7
  • 1
    What exactly is the problem? Does it throw an error? Or you're struggling to keep its value between the method calls? – julianobrasil Sep 06 '19 at 11:20
  • This looks like a typical subscription problem to me, you are accessing data that is not yet set (it will be set in "subscribe" block when `http` request completes)... – miselking Sep 06 '19 at 11:32
  • @miselking, yeah, it seems to me too. I've posted an answer in that way. – julianobrasil Sep 06 '19 at 11:34

2 Answers2

2

It seems to me that you're trying to get some info from an async function and use it in a synchronous way. Try this:

import {of} from 'rxjs';
import {map} from 'rxjs/operators';

@Pipe({ name: 'currency' })
export class CurrencyPipe implements PipeTransform {
  constructor(private httpService: HttpClient) { }
  transform(value, country): Observable<string> {
    if (!value) {
      return of(''); // had forgotten this line
    } else {
      if (!country) {
        country = 'NZD'
      }
      const symbol = symbols[country] //value of symbol is $
      if (symbol) {
        return this.httpService.get('./assets/locales/en_AU.json').pipe(
          map(data => accounting.formatMoney(value, { symbol, format: '%s %v',precision : data.CURRENCYFORMATS.AUD.CURRENCYDECIMALS , thousand: ",",
            decimal : "." }));
      }
      return of(accounting.formatMoney(value, { symbol: country, format: '%v %s' }));
    }
  }
}

And you can use it like this (to get R$ 12,00 on screen):

<div>
  {{12 | currency: 'BRL' | async}}
</div>
julianobrasil
  • 8,954
  • 2
  • 33
  • 55
  • I am facing errors with the above code. 1. Type '""' is not assignable to type 'Observable'.ts // am getting this error at return ' ' 2. I am not getting the json values inside data object. 3. Type 'Observable' is not assignable to type 'Observable'. Type 'void' is not assignable to type 'string' at return httpservice line – angie Sep 07 '19 at 15:25
  • Yeah, I had forgotten one thing on the pipe (when `value` was a falsey at the first `if`). Fixed the code in my answer. – julianobrasil Sep 08 '19 at 00:20
  • BTW, @Mensur's comment about not making an http call inside a pipe in his answer should be taken into account. – julianobrasil Sep 08 '19 at 00:25
  • Facing error at httpservice line - Type 'Observable' is not assignable to type 'Observable'. Type 'void' is not assignable to type 'string' – angie Sep 09 '19 at 04:55
  • Take away the parentheses from the function inside the map (or add a `return` statement before `accounting.form...`. – julianobrasil Sep 09 '19 at 09:28
  • Sorry, not the parentheses, but the curly brackets. – julianobrasil Sep 09 '19 at 09:29
  • Ok after making the above changes, I am not getting the values inside data Object. As a result, I get error, "Property 'CURRENCYFORMATS' does not exist on type 'Object'." – angie Sep 09 '19 at 09:42
0

First of all: You should definitely NOT make http calls in pipe. You are making a bazillion of unnecessary api calls.

Imagine you have a product page with 200 prices listed. Your implementation would fire 200 requests only to format the prices on your page for every visit. And on the other hand, you are not unsubscribing the subscriptions. This could quite easily lead to memory leaks.

TLDR:

Just use the default Currency Pipe which comes with angular. It should be sufficient for your use case.