mafortis
mafortis

Reputation: 7128

Using angular pipe globally

I am working on Ionic project with angular, I need to use pipe for almost all my pages but I am getting errors:

Logic

  1. If I use declarations in one of my pages pipe works just fine
  2. If I add same declarations in another page it returns error that this pipe has been used twice and I might consider using upper module.
  3. If I add my pipe to app.module.ts file and try to access it in my pages it says pipe not found!

Any idea how to get my pipe globally?

Code

app.module.ts

import { KeepHtmlPipe } from './pipes/keep-html.pipe';

@NgModule({
  declarations: [AppComponent, KeepHtmlPipe],
  entryComponents: [],
  imports: [
    HttpClientModule,
    FormsModule,
    CommonModule,
    ReactiveFormsModule,
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    VariationsPageModule
  ],
  providers: [
    StatusBar,
    SplashScreen,
    LaunchReview,
    NativeStorage,
    ImagePicker,
    Camera,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

pipe

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({
  name: 'keepHtml'
})
export class KeepHtmlPipe implements PipeTransform {

  constructor(private sanitizer: DomSanitizer) {
  }

  transform(content) {
    return this.sanitizer.bypassSecurityTrustHtml(content);
  }
}

usage in html files

<div [innerHTML]="product.stars | keepHtml"></div>

Update

based on answers I've made new file pipes.module.ts

import { NgModule } from '@angular/core';
import { KeepHtmlPipe } from './keep-html.pipe';

@NgModule({
    declarations: [
        KeepHtmlPipe
    ],
    imports: [],
    exports: [
        KeepHtmlPipe
    ]
})

Then add it to my app.module.ts

import { PipesModule } from './pipes/pipes.module';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    HttpClientModule,
    FormsModule,
    CommonModule,
    PipesModule, //here
    ReactiveFormsModule,
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    VariationsPageModule
  ],
  providers: [
    StatusBar,
    SplashScreen,
    LaunchReview,
    NativeStorage,
    ImagePicker,
    Camera,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

And in my pages I add this:

import { KeepHtmlPipe } from 'src/app/pipes/keep-html.pipe';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [FavoritesPage, KeepHtmlPipe], //here
  exports: [
    KeepHtmlPipe //and here
  ]
})
export class FavoritesPageModule {}

Now I'm getting this error:

ERROR Error: Uncaught (in promise): Error: Type KeepHtmlPipe is part of the declarations of 2 modules: PipesModule and FavoritesPageModule! Please consider moving KeepHtmlPipe to a higher module that imports PipesModule and FavoritesPageModule. You can also create a new NgModule that exports and includes KeepHtmlPipe then import that NgModule in PipesModule and FavoritesPageModule.

Upvotes: 2

Views: 3165

Answers (3)

Jacques
Jacques

Reputation: 3774

Posting an answer to try and help explain some things.

As answered by others, you need to create a "shared" module of some kind. In your update, you've named it PipesModule, so I will use that from here on.

Pipes Module:

import { NgModule } from '@angular/core';
import { KeepHtmlPipe } from './keep-html.pipe';

@NgModule({
    declarations: [
        KeepHtmlPipe
    ],
    imports: [],
    exports: [
        KeepHtmlPipe
    ]
})

Now, when you import this into any other module, you will automattically have access to KeepHtmlPipe.

FavoritesPageModule:

import { PipesModule } from 'src/app/pipes/pipes.module';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonicModule,
    PipesModule,
    RouterModule.forChild(routes)
  ],
  declarations: [
    FavoritesPage
  ]
})
export class FavoritesPageModule {}

Adding PipesModule to the imports here gives you access to the KeepHtmlPipe that was exported in the PipesModule in any component declared in this module (IE: Part of the declarations list).

favorites-page.component.html

<div [innerHTML]="product.stars | keepHtml"></div>

This should now work fine.

Upvotes: 4

Smokey Dawson
Smokey Dawson

Reputation: 9230

What you want to do is create a shared module, that your other modules can import. This was you can re-use components, pipes, module etc.. in any module!

You can do the following (you will have to remove KeepHtmlPipe from the current module)

import { CommonModule } ...
import { NgModule } ...

import { KeepHtmlPipe } ...

// ...

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    KeepHtmlPipe
  ],
  exports: [
    KeepHtmlPipe
  ]
})
export class SharedModule {}  

!important - you must export the KeepHtmlPipe

then in your app.module

import { SharedModule } from ...

// ...

imports: [
   SharedModule
]

now you can use your pipe anywhere in your app, and in future if you want to add any more global pipes, directives or components they can go in this SharedModule

Upvotes: 3

andypotato
andypotato

Reputation: 722

I recommend to create a module containing all your global pipes, then import the module in your app module. Here's how you do it:

1) Create pipes.module.ts inside src/pipes folder

import { NgModule } from '@angular/core';
import { KeepHtmlPipe } from './keep-html.pipe';

@NgModule({
    declarations: [
      KeepHtmlPipe
    ],
    imports: [],
    exports: [
      KeepHtmlPipe
    ]
})
export class PipesModule {}

2) In your app.module import the PipesModule and add it to the imports collection

import { PipesModule } from '../pipes/pipes.module';

[...]

@NgModule({
  declarations: [
    MyApp
  ],
  imports: [
    [...]
    PipesModule
  ],
[...]

Afterwards you can use your pipe anywhere in the app. If you add more global pipes later just also add it to your PipesModule.

Upvotes: 2

Related Questions