How to make custom pipes application-wide?

The code below does not seem to work when I attempt to use the pipe on a page within my app. I am not sure if the App decorator works in this manner or if I am missing something. The idea is to not have to inject CustomPipe into every page that needs it as most pages will use it.

import {CustomPipe} from './pipes/customPipe';

@App({
    templateUrl: 'build/app.html',
    config: { },
    pipes: [CustomPipe]
})

Injencting in each page does work, if that pipe should be imported in a lot of the files in the app it makes sense to make it available through the whole app.

As some config options carry away through the app as the providers, then it’s logic to think that you can do the same with pipes but i think of pipes more like directives, they have to be injected in the component where they will be used, so injecting a pipe as global instance in the app’s config probably won’t work.

If you ask why, i think providers are the exception, they carry data between components so it makes sense to be able to inject it as a global singleton instance, but pipes and directives changes the html structure, so in order to lower the overhead of looking up for the selector through all the app you have to inject it in each specific component that uses it, at least that’s what i think Angular 2 is doing with the configs, correct me if i’m wrong. :confused:

Oh so thats why. Makes sense to me

Please don’t take my word for it, i think that’s the reason it doesn’t work.
@brandyshea could you actually confirm my suspicions?

Is there a way of including this pipes as PLATFORM_PIPES?
See: https://angular.io/docs/js/latest/api/core/PLATFORM_PIPES-let.html

It seems like the right thing to do: we should be able to add this special providers at @App/providers.

Interesting, didn’t know about this in the Angular docs, idk, give me time to dig the app code and see if that property of the bootstrap function is exposed to the @app annotation constructor.

Here’s the lines of interest:
https://github.com/driftyco/ionic/blob/2.0/ionic/decorators/app.ts#L58-L62
https://github.com/driftyco/ionic/blob/2.0/ionic/config/bootstrap.ts#L50-L66

Theoretically it is possible but i’m not sure how would we go about it, could you test with this?:

import {PLATFORM_PIPES} from 'angular2/core';
import {OtherPipe} from './myPipe';
@App({
  template: `
    {{123 | other-pipe}}
  `,
  providers: [provide(PLATFORM_PIPES, {useValue: [OtherPipe], multi:true})]
})
export class MyApp {
  ...
}

I can confirm that it works. There was only an import missing in your example:

import {provide, PLATFORM_PIPES} from 'angular2/core';
import {OtherPipe} from './myPipe';
@App({
    template: `{{ 123 | other-pipe }}`,
    providers: [provide(PLATFORM_PIPES, {useValue: [OtherPipe], multi:true})]
})
export class MyApp {
    ...
}
3 Likes

Holly sh*7 i didn’t tough it would work, i’m gonna bookmark this topic.

@eillarra How would it be if i want to use this but with directives?

For future reference to all, the way to provide global services is up there as i stated and @eillarra corrected
For global components or directives use the following (Seems weird but it works, take note that i have to provide it to the providers array, and use the PLATFORM_DIRECTIVES instead of PLATFORM_PIPES or any other platform related variable):

import {provide, PLATFORM_DIRECTIVES} from 'angular2/core';
import {NewComponent} from './components/components';

@App({
  templateUrl: 'build/app.html',
  providers: [
    provide(PLATFORM_DIRECTIVES, {useValue: [NewComponent], multi: true})
  ],

1 Like

Also it seems the directives now will be global by default, relate to issue: #6092

works for me … thanks, now i can inject as global pipe :smiley:

So this is working fine by adding it to platform Providers in Angular2 projects, I prefer to not use it in a dirty way as adding it to providers.

Anyone seen a solution without hacking around?

It seems this is not working on beta 0.8 and up, because @App is replaced with @Component

I tried in @Componet and it isn’t work, but it works in ionicBootstrap

ionicBootstrap(MyApp, [
          provide(PLATFORM_DIRECTIVES, { useValue: [PastaWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [PastaBtnWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [ExtratoWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [ExtratoBtnWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [ChequeWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [ChequeBtnWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [ReciboWrapper], multi: true }),
          provide(PLATFORM_DIRECTIVES, { useValue: [ReciboBtnWrapper], multi: true })
]);

Thanks @eillarra and @luchillo17, you guys save me hours in a circular include problem!

WTF is that? why so much provide? the useValue property is an array, just put all those inside the array, that way you’ll save some overhead in calling the provide function.

Oh, I must did something wrong first time I tried userValue as an array, because dind’t work and I assumed that userValue wasn’t an array !

Well if you typed userValue instead of useValue i’m not surprised, did you try again and worked?

Just make sure you typed the right property name, and that all those are directives, if they are services or providers they go outside of the provide in the ionicBootstrap providers array.

Yes, now it’s working! Maybe was something like that, I typed user instead use