The pipe ' ' could not be found angular2 custom pipe

212,952

Solution 1

Make sure you are not facing a "cross module" problem

If the component which is using the pipe, doesn't belong to the module which has declared the pipe component "globally" then the pipe is not found and you get this error message.

In my case I've declared the pipe in a separate module and imported this pipe module in any other module having components using the pipe.

I have declared a that the component in which you are using the pipe is

the Pipe Module

 import { NgModule }      from '@angular/core';
 import { myDateFormat }          from '../directives/myDateFormat';

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

 export class PipeModule {

   static forRoot() {
      return {
          ngModule: PipeModule,
          providers: [],
      };
   }
 } 

Usage in another module (e.g. app.module)

  // Import APPLICATION MODULES
  ...
  import { PipeModule }    from './tools/PipeModule';

  @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],

Solution 2

You need to include your pipe in module declaration:

declarations: [ UsersPipe ],
providers: [UsersPipe]

Solution 3

For Ionic you can face multiple issues as @Karl mentioned. The solution which works flawlessly for ionic lazy loaded pages is:

  1. Create pipes directory with following files: pipes.ts and pipes.module.ts

// pipes.ts content (it can have multiple pipes inside, just remember to

use @Pipe function before each class)
import { PipeTransform, Pipe } from "@angular/core";
@Pipe({ name: "toArray" })
export class toArrayPipe implements PipeTransform {
  transform(value, args: string[]): any {
    if (!value) return value;
    let keys = [];
    for (let key in value) {
      keys.push({ key: key, value: value[key] });
    }
    return keys;
  }
}

// pipes.module.ts content

import { NgModule } from "@angular/core";
import { IonicModule } from "ionic-angular";
import { toArrayPipe } from "./pipes";

@NgModule({
  declarations: [toArrayPipe],
  imports: [IonicModule],
  exports: [toArrayPipe]
})
export class PipesModule {}
  1. Include PipesModule into app.module and @NgModule imports section

    import { PipesModule } from "../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] });

  2. Include PipesModule in each of your .module.ts where you want to use custom pipes. Don't forget to add it into imports section. // Example. file: pages/my-custom-page/my-custom-page.module.ts

    import { PipesModule } from "../../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] })

  3. Thats it. Now you can use your custom pipe in your template. Ex.

<div *ngFor="let prop of myObject | toArray">{{ prop.key }}</div>

Solution 4

I found the "cross module" answer above very helpful to my situation, but would want to expand on that, as there is another wrinkle to consider. If you have a submodule, it also can't see the pipes in the parent module in my testing. For that reason also, you may need to put pipes into there own separate module.

Here's a summary of the steps I took to address pipes not being visible in the submodule:

  1. Take pipes out of (parent) SharedModule and put into PipeModule
  2. In SharedModule, import PipeModule and export (for other parts of app dependent on SharedModule to automatically gain access to PipeModule)
  3. For Sub-SharedModule, import PipeModule, so it can gain access to PipeModule, without having to re-import SharedModule which would create a circular dependency issue, among other problems.

Another footnote to the above "cross module" answer: when I created the PipeModule I removed the forRoot static method and imported PipeModule without that in my shared module. My basic understanding is that forRoot is useful for scenarios like singletons, which don't apply to filters necessarily.

Solution 5

Suggesting an alternative answer here:

Making a separate module for the Pipe is not required, but is definitely an alternative. Check the official docs footnote: https://angular.io/guide/pipes#custom-pipes

You use your custom pipe the same way you use built-in pipes.
You must include your pipe in the declarations array of the AppModule . If you choose to inject your pipe into a class, you must provide it in the providers array of your NgModule.

All you have to do is add your pipe to the declarations array, and the providers array in the module where you want to use the Pipe.

declarations: [
...
CustomPipe,
...
],
providers: [
...
CustomPipe,
...
]
Share:
212,952
Sumama Waheed
Author by

Sumama Waheed

Updated on April 16, 2022

Comments

  • Sumama Waheed
    Sumama Waheed about 2 years

    I can't seem to fix this error. I have a search bar and an ngFor. I am trying to filter the array using a custom pipe like this:

    import { Pipe, PipeTransform } from '@angular/core';
    
    import { User } from '../user/user';
    
    @Pipe({
      name: 'usersPipe',
      pure: false
    })
    export class UsersPipe implements PipeTransform {
      transform(users: User [], searchTerm: string) {
        return users.filter(user => user.name.indexOf(searchTerm) !== -1);
      }
    }
    

    Usage:

    <input [(ngModel)]="searchTerm" type="text" placeholder="Search users">
    
    <div *ngFor="let user of (users | usersPipe:searchTerm)">
    ...
    </div>
    

    Error:

    zone.js:478 Unhandled Promise rejection: Template parse errors:
    The pipe 'usersPipe' could not be found ("
    <div class="row">
        <div  
        [ERROR ->]*ngFor="let user of (user | usersPipe:searchTerm)">
    

    Angular versions:

    "@angular/common": "2.0.0-rc.5",
    "@angular/compiler": "2.0.0-rc.5",
    "@angular/core": "2.0.0-rc.5",
    "@angular/platform-browser": "2.0.0-rc.5",
    "@angular/platform-browser-dynamic": "2.0.0-rc.5",
    "@angular/router": "3.0.0-rc.1",
    "@angular/forms": "0.3.0",
    "@angular/http": "2.0.0-rc.5",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "0.1.3",
    "rxjs": "5.0.0-beta.6",
    "systemjs": "0.19.26",
    "bootstrap": "^3.3.6",
    "zone.js": "^0.6.12"
    
    • Harry Ninh
      Harry Ninh almost 8 years
      Did you include it in the Component's Pipes ?
    • Sumama Waheed
      Sumama Waheed almost 8 years
      I just realized that was the reason. How come the angular example for custom pipe never does this: angular.io/resources/live-examples/pipes/ts/plnkr.html
    • Harry Ninh
      Harry Ninh almost 8 years
      They defined it as global pipe. You can do the same to your custom pipe if you use it in many places and don't want to define in every single annotation.
    • Michelangelo
      Michelangelo almost 8 years
      @SumamaWaheed I am pretty sure that it was there at some point in the docs, but you are correct the docs now don't mention/show it.
  • ABabin
    ABabin almost 8 years
    In the Plunker you posted above, the pipes are imported in the app module (exactly as you do with the components themselves) which makes the pipe available for all components in that module.
  • Sumama Waheed
    Sumama Waheed almost 8 years
    Oh ok I was actually looking at the component that actually uses the custom pipe. I didn't know it could be imported globally in the app module . Thanks
  • Salvatore Pannozzo Capodiferro
    Salvatore Pannozzo Capodiferro over 7 years
    users-filter.pipe? why .pipe?
  • Sumama Waheed
    Sumama Waheed over 7 years
    That's just a naming convention, the file is called users-filter.pipe.ts
  • Sumama Waheed
    Sumama Waheed over 7 years
    @SachinThampan could be because this was when angular was in rc5 I think..things changed since then specially with NgModule. Please look at the docs for NgModule
  • AJ Zane
    AJ Zane over 7 years
    This solution was the only one that worked for me. Turns out pipes are required to have a module
  • Greg A
    Greg A over 7 years
    Just a note, I originally just included the pipe in the providers. This needs to be included in both declarations and providers in the module file.
  • CNSKnight
    CNSKnight about 7 years
    I too found this to partially solve my pipe not found error in Ng 2.8.* Additionally, I had typescript "warnings" related only to the naming conventions in use, which upon solving these, contributed to this custom pipe transpiling properly and ultimately being found in the template.
  • user1501382
    user1501382 about 7 years
    I was struggling until i followed your suggestion. i wasted around 4 hr's to just figure it out. Thank you for the suggestion.
  • lulu88
    lulu88 about 7 years
    This is truly the only solution that worked for me! I tried the whole shared module thing, but this solution worked like a charm. Thank you @Karl!
  • Martijn
    Martijn over 6 years
    Why isn't this documented? The documentation states You must include your pipe in the declarations array of the AppModule. : angular.io/guide/pipes. Anyway, your answer also fixes my problem.
  • Vinicios Torres
    Vinicios Torres over 6 years
    Thanks, Yuvals. I add a detail: declaration of module where you need the pipe.
  • jmcgrath207
    jmcgrath207 over 6 years
    Thank you for adding this. It only worked for me once it was added to Sub-SharedModule
  • apoorva
    apoorva over 6 years
    how do we test this in our component test,
  • Precastic
    Precastic over 6 years
    Don't forget to also include exports: [UsersPipe] if the module is going to be imported by other modules.
  • tenderloin
    tenderloin about 6 years
    Yeah same here, the part I was missing was importing PipesModule into the Sub-SharedModule.
  • Rafique Mohammed
    Rafique Mohammed about 6 years
    Thanks! My problem was i missed "exports:[myPipe]" thinking that exports are only for modules!
  • karlis
    karlis about 6 years
    the only way I got it to work out. Looks like pipes should not be in shared module with other components and directives
  • ykadaru
    ykadaru about 5 years
    I don't think adding the Pipe to a separate module is required at all. Check the offical docs: angular.io/guide/pipes#custom-pipes It says Pipes have to be declared and provided, so it can be injectible. @AJZane
  • ykadaru
    ykadaru about 5 years
    I think this should be marked as the correct answer. The marked answer is misleading; it's just an alternative... but the most straightforward answer is this.
  • royappa
    royappa about 5 years
    This was a lifesaver for ionic, thanks. Because "ionic generate pipe ...." does not generate all the steps needed, like creating the pipes.module.ts. Your approach worked perfectly. Note, for ionic v4, some small changes are needed to the import paths.
  • royappa
    royappa about 5 years
    I found that you don't need the imports in app.module.ts, so that step can be omitted. It must be because it the "shared module" is anyway being imported into each other module where it is needed. It would be nice if the app.module import worked globally, but I tried and it doesn't.
  • Himanshu Bansal
    Himanshu Bansal over 4 years
    But a single pipe can not be a part of 2 modules.... The above approach make it more approachable in different modules.
  • Marcus
    Marcus about 4 years
    I also like this answer. At first it did not seem to work for me because ng serve didn't pick up this change. I had to kill it and used the ng serve command again to rebuild everything.
  • Sahal
    Sahal about 4 years
    @karlis I am getting error : Failed: Template parse errors: The pipe 'keys' could not be found ("<div class="form-control-feedback" *ngFor="let control of controlsInternal"> <p *ngFor="let e[ERROR ->]rror of control?.errors | keys"> <span *ngIf="!control?.untouched && control.errors[error]">{"): ng:///DynamicTestModule/FormErrorsComponent.html@1:20 How can i resolve it ?
  • mircobabini
    mircobabini almost 4 years
    I'm still facing this: CONSOLE ERROR file: node_modules/@angular/core/fesm5/core.js:4002:0 ERROR Error: Uncaught (in promise): NullInjectorError: StaticInjectorError(AppModule)[ToHtmlPipe -> DomSanitizer]: StaticInjectorError(Platform: core)[ToHtmlPipe -> DomSanitizer]: NullInjectorError: No provider for DomSanitizer!
  • maniB
    maniB over 3 years
    This solution worked for me except that PipeModule had to import CommonModule. More research revealed that pipe, directives, etc. can be declared in one module only. If you have to use your custom pipe in a single module/component then you can directly import the pipe. But if you are planning to reuse the pipe in multiple modules, then the only way is to create another module (like PipeModule above) and then import this module in other modules.
  • Ebsan
    Ebsan over 3 years
    I'm still confused as to what actually fixes the issue. In #2 you say 'export for other parts of app to automatically gain access' but then in #3 you say to import PipeModule into the Sub-SharedModule. The Sub-SharedModule already is importing SharedModule right? Why do we need to import PipeModule as well, if we're exporting it already in SharedModule?
  • sarora
    sarora over 3 years
    Good question - to be clear.. by Sub-SharedModule i mean a module that is imported into SharedModule, NOT something that is already importing SharedModule. In this scenario, the Sub SharedModule doesn't get access to PipesModule.