The pipe ' ' could not be found angular2 c

2019-01-06 12:52发布

问题:

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"

回答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()
    ....
  ],


回答2:

You need to include your pipe in module declaration:

declarations: [ UsersPipe ],
providers: [UsersPipe]


回答3:

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.



回答4:

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>



回答5:

Note : Only if you are not using angular modules

For some reason this is not in the docs but I had to import the custom pipe in the component

import {UsersPipe} from './users-filter.pipe'

@Component({
    ...
    pipes:      [UsersPipe]
})


回答6:

I have created a module for pipes in the same directory where my pipes are present

import { NgModule } from '@angular/core';
///import pipe...
import { Base64ToImage, TruncateString} from './'  

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

    export class SharedPipeModule { }   

Now import that module in app.module:

import {SharedPipeModule} from './pipe/shared.pipe.module'
 @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],

Now it can be used by importing the same in the nested module