I have a very simple Pipe in Angular 5
import { Pipe, Injectable } from '@angular/core';
@Pipe({
name: "default"
})
@Injectable()
export class DefaultPipe {
transform(value: string, fallback: string): string {
let image = "";
if (value) {
image = value;
} else {
image = fallback;
}
return image;
}
}
and I use it in a very simple way just for demonstration
<div>
{{ 'somthing' | default }}
</div>
I have also added in provider section in app.module.ts
@NgModule({
declarations: [
AppComponent,
DefaultPipe // <-- Here
],
imports: [
....
],
providers: [
....
],
bootstrap: [AppComponent]
})
export class AppModule { }
when you use it in an normal component such as
app.component.html
it works fine, but if you use it in a component which is used in a child route it gives this error:
compiler.js:486 Uncaught Error: Template parse errors: The pipe 'default' could not be found ("
{{[ERROR ->] 'somthing' | default }} "): ng:///AppRoutingModule/LoginComponent.html@75:6 at syntaxError (compiler.js:486) at TemplateParser.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.TemplateParser.parse (compiler.js:24674) at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._parseTemplate (compiler.js:34629) at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileTemplate (compiler.js:34604) at compiler.js:34505 at Set.forEach () at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileComponents (compiler.js:34505) at compiler.js:34375 at Object.then (compiler.js:475) at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:34374)
To Solve:
I added this module as share.module.ts
import { NgModule } from '@angular/core';
import { DefaultPipe } from './core/pipes/default.pipe';
@NgModule({
declarations: [DefaultPipe],
exports: [DefaultPipe]
})
export class SharedModule { }
and used it in 2 places, one in app.module.ts:
@NgModule({
declarations: [
AppComponent,
],
imports: [
...
// other modules
...
SharedModule
],
providers: [
....
],
bootstrap: [AppComponent]
}) export class AppModule { }
and one in route.module.ts
@NgModule({
declarations: [
....
],
imports: [
....
SharedModule
],
exports: [
RouterModule,
]
})
export class AppRoutingModule { }
You dont need to use the Injectable
decorator on the pipe, so you can remove that.
Furthermore, as already suggested in other answers, I would recommend you to explicitely implement the PipeTransform
interface in order to be consistent with the pipe API.
compiler.js:486 Uncaught Error: Template parse errors: The pipe 'default' could not be found ("
{{[ERROR ->] 'somthing' | default }} "): ng:///AppRoutingModule/LoginComponent.html@75:6 at syntaxError (compiler.js:486)
is basically saying that your pipe wasnt neither declared or imported in the module, in whichLoginComponent
is declared.
The simplest and cleanest solution would be to declare/export the pipe inside of a new NgModule class, that you can then import into every module that declares a component that uses the pipe. For example:
@NgModule({
declarations: [DefaultPipe],
exports: [DefaultPipe]
})
export class DefaultPipeModule{}
@NgModule({
imports: [DefaultPipeModule],
declarations: [LoginComponent]
})
export class FooModule {}
@NgModule({
imports: [DefaultPipeModule],
declarations: [FooComponent] // fooComponent also uses the default pipe, so we need to import its module
})
export class SomeOtherModule{}