No Provider for CustomPipe - angular 4
Asked Answered
I

3

92

I've a custom decimal format pipe that uses angular Decimal pipe inturn. This pipe is a part of the shared module. I'm use this in feature module and getting no provider error when running the application.

Please ignore if there are any typo.

./src/pipes/custom.pipe.ts

import { DecimalPipe } from '@angular/common';
..
@Pipe({
    name: 'customDecimalPipe'
})
...
export class CustomPipe {
constructor(public decimalPipe: DecimalPipe) {}
transform(value: any, format: any) {
    ...
}

./modules/shared.module.ts

import  { CustomPipe } from '../pipes/custom.pipe';

...

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

I inject the custom pipe in one of the components and call transform method to get the transformed values. The shared module is imported in he feature module.

Interlineate answered 19/9, 2017 at 12:2 Comment(1)
Possible duplicate of Angular 2/4 use pipes in services and componentsGrackle
D
186

If you want to use pipe's transform() method in component, you also need to add CustomPipe to module's providers:

import  { CustomPipe } from '../pipes/custom.pipe';

...

@NgModule({
  imports:      [ .. ],
  declarations: [ CustomPipe ],
  exports:    [ CustomPipe ],
  providers:    [ CustomPipe ]
})
export class SharedModule { }
Drunkard answered 19/9, 2017 at 12:7 Comment(4)
Thank you for your answer. so that means the Pipe becomes an injectable so it has to be provided. am i right.?Interlineate
@Interlineate Exactly.Drunkard
But, does that deviate form angular's shared module definition. ?Interlineate
@Interlineate you can add the CustomPipe to the *ServiceModule*(if you have a dedicated one) or any feature module instead of the shared one.Drought
D
26

Apart from adding the CustomPipe to the module's provider list, an alternative is to add to the component's providers. This can be helpful if your custom pipe is used in only a few components.

import  { CustomPipe } from '../pipes/custom.pipe';
...
@Component({
    templateUrl: './some.component.html',
    ...
    providers: [CustomPipe]
})
export class SomeComponent{
    ...
}

Hope this helps.

Drought answered 16/5, 2018 at 16:53 Comment(2)
This makes much more sense than the accepted answer (cannot believe upvotes are 10x less)! A pipe designed for a specific component should not be available globally. Appreciated the logic Faruq.Cecilius
This only seems to be working if solely used in TypeScript. Trying to use it in template by name resulted in an error unless adding to module's declarations.Occidental
G
18

You could also make the pipe Injectable (the same way it is done with the services you create using the cli):

    import { Injectable, Pipe, PipeTransform } from '@angular/core';

    @Pipe({
      name: 'customDecimalPipe'
    })
    @Injectable({
      providedIn: 'root'
    })
    export class CustomPipe extends PipeTransform {
      ...
    }
Greenheart answered 27/4, 2019 at 18:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.