Angular2 Using Pipes in Component.js
Asked Answered
D

2

9

I'm learning Angular2 and I want to format a number adding thousand comma separator. As far as I have read this can be done using Pipes, the thing is that I want to format the number programmatically in the js file not in html (doing like var | number).

First of all I've realized there is no NumberPipe standalone pipe that I can work with (correct me if I'm wrong) the most similar one is CurrencyPipe in @angular2/common. So I have something like this:

import { Component } from '@angular/core';
import { CurrencyPipe } from '@angular/common';

@Component({
  templateUrl: 'test.component.html',
  styleUrls: ['./test.component.scss']
})
export class TestComponent {
    public myNumber = 1000;

    constructor(private currencyPipe: CurrencyPipe) {    
        var formatted = this.currencyPipe().transform(this.myNumber, 'MXN', true); // Is this correct?
    }

}

But it throws me the following error: Unhandled Promise rejection: No provider for CurrencyPipe! ; Zone: angular ;...

What am I doing wrong?

Thanks in advance.

Regards

Distrust answered 24/1, 2017 at 22:40 Comment(2)
why not use it like {{ myNumber | currency:'USD':true }}Euphrosyne
@Euphrosyne Because I'm retrieving data from an API a using it to draw a Chart.js chart... No HTML here, so I can't use it {{myNumber | currency}}, I need to format the data programatically.Distrust
D
15

First thing: you need to declare your pipe - add it to the NgModule declarations section:

declarations: [CurrencyPipe]

Second thing: pipes are not injectables, so you can't take its instance by using Angular dependency injection system. You need to create new instance of this pipe manually, like:

var formatted = (new CurrencyPipe()).transform(this.myNumber, 'MXN', true);
Dalrymple answered 25/1, 2017 at 2:1 Comment(5)
This works... but I had to pass a locale id string as a parameter to CurrencyPipe when creating the instance like this: return new CurrencyPipe('es-MX').transform(this.myNumber, 'MXN', true);Distrust
@Daniel Kucal - You suggested to 'provide' the pipe, by adding it to providers array. This looks confusing, as what I have learnt so far only services are provided, Components, Pipes and Directives must be 'Imported' into 'Imports' array. Do I miss something here?Fascinator
Hi @DeepakPathak, thanks for your question, the instruction here was outdated and causing an error. In previous Angular version it was also working with pipe added to component's (that's important) providers, I've updated the answer. Components, pipes and directives should be placed in declarations. imports is for importing one NgModule into another.Dalrymple
@DanielKucal - Appreciate your response and update. Happy Coding!Fascinator
There is new format for the display parameter as per this document. TLDR: a boolean value is deprecated, use one of the string values instead.Demarcusdemaria
E
1

This actually works in an @Injectable display utility service with even less fuss than the previous answer involving modules. I imported my data model (below) and the pipe, then simply added the function. So, if you can't use the pipe directly in markup, use this trick!

export interface MoneyDTO extends SerializableDTO, JsonModelObjectDTO {
  value?: string;
  currency?: string;
}

import { CurrencyPipe } from '@angular/common';

formatMoney(money: MoneyDTO): string {
  const cp: CurrencyPipe = new CurrencyPipe('en-US');

  return money && money.value ? cp.transform(money.value, money.currency || 'USD', 'symbol') : null;
}
Evelinevelina answered 30/4, 2019 at 22:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.