vdvaxel
vdvaxel

Reputation: 137

Angular custom pipe not working 'pipe not found'

I am trying to create a custom pipe in my Angular app but keep getting the 'no pipe found with name "currencyFormat"' error message. I created the pipe using Angular CLI: ng g pipe /components/pipes/currency-format, and the code looks like this:

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

@Pipe({
  name: 'currencyFormat'
})
export class CurrencyFormatPipe implements PipeTransform {
  transform(value: any, currency: string): any {
    const currencySymbol = (currency == 'EUR' ? '€' : '$');
    let formattedValue = `${currencySymbol} ${formatNumber(value, 'be', '1.2-2')}`;
    return formattedValue;
  }

}

Because I used the Angular CLI to create the pipe, the pipe is added to the declarations of app.module.ts automatically. I am trying to use the pipe in one of my page (home.page.html), but still I get this error. I've tried many different things so far, including putting the pipe in a separate module and trying to import that module, but without any success.

Any ideas what this issue might be?

EDIT: here is my app.module.ts as well, in case it's useful:

import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { ComponentsModule } from 'src/app/components/components.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ChartsModule } from 'ng2-charts';
import { environment } from "src/environments/environment";
import { AngularFireModule } from "@angular/fire";
import { AngularFirestoreModule } from "@angular/fire/firestore";
import { ServiceWorkerModule } from '@angular/service-worker';
import { CurrencyFormatPipe } from './components/pipes/currency-format.pipe';

@NgModule({
  declarations: [AppComponent, CurrencyFormatPipe],
  entryComponents: [],
  imports: [
    BrowserModule, 
    IonicModule.forRoot({ animated: true, mode: 'ios' }), 
    AppRoutingModule, 
    ComponentsModule,
    BrowserAnimationsModule,
    ChartsModule,
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFirestoreModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
  ],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Upvotes: 3

Views: 13374

Answers (2)

Barremian
Barremian

Reputation: 31105

If you have multiple modules, I believe you need to declare the pipe in one of the auxiliary modules apart from the AppModule and import the module in other modules (including AppModule) to use it.

I am not exactly sure why the pipes declared in AppModule don't have global access from other modules. It somehow goes against the lazy-loading mechanism of Angular.

Try the following

@NgModule({
    imports: [],
    declarations: [ CurrencyPipe ],
    exports: [ CurrencyPipe ]
})
export class ComponentsModule { }
@NgModule({
    imports: [ BrowserModule, HttpModule, FormsModule, ComponentsModule ],
    declarations: [ AppComponent ],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

You need to then import the module where the pipe is declared (ComponentModule in this example) whenever you need to use it other modules.

Upvotes: 2

DJ House
DJ House

Reputation: 1397

The best way to solve this issue to to have a common, Shared Module. This is a common pattern in Angular.

Given an example folder/app structure:


app
├── home
│   ├── home.component.ts
│   ├── home.module.ts
│   └── ...
├── shared
│   └── shared.module.ts
├── app.module.ts
└── ...

Then you declare and export components, pipes, directives, modules, etc in your shared.module that multiple other modules will need.

shared.module.ts

import { NgModule } from '@angular/core';

@NgModule({
  declarations: [
    /* declare it once, here */
    CurrencyFormatPipe
  ],
  exports: [
    /* then export it */
    CurrencyFormatPipe
  ]
})
export class SharedModule { }

All your other modules will just import your shared.module and be able to use anything the shared module exports.

app.module.ts

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule, 
    /* import your shared module here */
    SharedModule,

    IonicModule.forRoot({ animated: true, mode: 'ios' }), 
    AppRoutingModule, 
    ComponentsModule,
    BrowserAnimationsModule,
    ChartsModule,
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFirestoreModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
  ],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

And then you can also import it into your home.module.ts

@NgModule({
  declarations: [/* other imports */],
  entryComponents: [],
  imports: [
    /* import your shared module here, you will have access to the currency pipe now */
    SharedModule
  ],
})
export class AppModule {}

Hope that helps. Here are the Angular docs about shared modules.

Upvotes: 7

Related Questions