Search code examples
angulartypescriptpipeangular-module

How to declare a pipe globally to use in different modules?


I have a custom pipe named CurrConvertPipe

import {Pipe, PipeTransform} from '@angular/core';
import {LocalStorageService} from './local-storage';
@Pipe({name: 'currConvert', pure: false})
export class CurrConvertPipe implements PipeTransform {
  constructor(private currencyStorage: LocalStorageService) {}

  transform(value: number): number {
     let inputRate = this.currencyStorage.getCurrencyRate('EUR');
    let outputputRate = this.currencyStorage.getCurrencyRate(localStorage.getItem('currency'));
    return value / inputRate * outputputRate;
  }
}

I need to use this in two different modules, Module1 and Module2.
When I import in Module1 and Module2, I get an error saying it should be declared in a higher level module.

So I declare the pipe inside the app.module.ts

import './rxjs-extensions';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CurrConvertPipe } from './services/currency/currency-pipe';
@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        AppRoutingModule,
        Module1,         
        Module2

    ],

    declarations: [
        AppComponent,
        CurrConvertPipe
    ],
    providers: [

    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

But when I use it in Module1, it throws an error

The pipe 'currConvert' could not be found


Solution

  • In Angular a good technique for sharing common directives, components, pipes, etc. is to use a so called shared module.

    Those modules declare and export common parts, to make them usable for any of your other modules.

    The fundamentals section of the angular documentation is a very good read about shared modules.

    Let's take as example your currConvert pipe.

    • Declare new NgModule called ApplicationPipesModule

    • Add the pipe to the declarations and exports arrays of the NgModule-decorator metadata

    • Add any modules that may be required for your pipe to work to the imports array

      // application-pipes.module.ts
      // other imports
      import { CurrConvertPipe } from './{your-path}';
      
      @NgModule({
        imports: [
          // dep modules
        ],
        declarations: [ 
          CurrConvertPipe
        ],
        exports: [
          CurrConvertPipe
        ]
      })
      export class ApplicationPipesModule {}
      
    • import the created ApplicationPipesModule module into the modules where your pipe is going to be used, by adding it to the imports array

      // my-module1.module.ts
      // other imports
      import { ApplicationPipesModule } from './{your-path}';   
      
      @NgModule({
       imports: [
         // other dep modules
         ApplicationPipesModule
       ],
       declarations: [],
       exports: []
      })
      export class MyModule1 {}