Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Pipes executing before ngOnInit

I have a implemented a custom Pipe in Angular 2 RC5 which processes data that I get from the server. The problem I'm having is that the Pipe executes before the ngOnInit which is where I am making the calls to the server.

As a test I passed an-already populated list to the Pipe and everything works as expected. The only issue I'm having is that the Pipe executes when the page is rendered. And so the list in that case is empty.

Is there any way to "delay" the rendering of the page so that when the Pipe executes it has the data retrieved from the server?

This is a sample of my code:

Component

ngOnInit() {
    Observable.forkJoin([
        this.testService.get(),
        this.multilingualService.get(localStorage.getItem('currentPage'))
    ]).subscribe(servicesResult => {
        this.mainList = servicesResult[0];
        this.pageMultilinguals = servicesResult[1];
    },
    error => this.handleError(error));
}

Pipe

@Pipe({name: 'multiLang'})
export class MultilingualPipe implements PipeTransform {
    transform(value: string, pageMultilinguals: Multilingual[], context: number): string {

        for (let i = 0; i < pageMultilinguals.length; i++) {
            if (pageMultilinguals[i].reference === value && pageMultilinguals[i].contexTypeId === context) {
                return pageMultilinguals[i].value;
            }
        }
    }
}

Template

<span>{{ 'Test' | multiLang: pageMultilinguals: 9 }}</span>
like image 638
Daniel Grima Avatar asked Sep 06 '16 15:09

Daniel Grima


People also ask

Can I use two pipes in Angular?

No Filter Pipe Or OrderBy Pipe: Luckily, now these two pipes are not available in Angular 2 and instead Angular allows us to write custom pipes so we can write the custom pipes according to the logic we like to use. So let's see how to create the custom pipes.

How are pipes executed in Angular?

You use data binding with a pipe to display values and respond to user actions. If the data is a primitive input value, such as String or Number , or an object reference as input, such as Date or Array , Angular executes the pipe whenever it detects a change for the input value or reference.

Can pipes be chained in Angular?

What Is Chaining Pipe? The chaining Pipe is used to perform the multiple operations within the single expression. This chaining operation will be chained using the pipe (I). In the following example, to display the birthday in the upper case- will need to use the inbuilt date-pipe and upper-case-pipe.

Can we use pipes in TS file?

use date pipe in component ts files In laterst version of Angular i.e., from version 6 we can directly use angular pipes's public methods inside the components to format the values. For example we use date pipe format method formatMethod in component file by importing it from the @angular/common as shown below.


1 Answers

When Angular runs change detection the, then the pipe is executed the first time. After the first change detection run, ngOnInit() is called. Delaying the call to your pipe until ngOnInit() wouldn't help at all, because when you make the server call in ngOnInit() doesn't mean you get the response immediately. The HTTP request is an async call and the response comes eventually but ngOnInit() will be completed a long time already.

I think in your case it should be enough to just make the pipe safe for null values so it doesn't cause exceptions when the passed values are null:

@Pipe({name: 'multiLang'})
export class MultilingualPipe implements PipeTransform {
    transform(value: string, pageMultilinguals: Multilingual[], context: number): string {
        if(!value || !pageMultilinguals || !context) {
          return null;
        }
        for (let i = 0; i < pageMultilinguals.length; i++) {
            if (pageMultilinguals[i].reference === value && pageMultilinguals[i].contexTypeId === context) {
                return pageMultilinguals[i].value;
            }
        }
    }
}
like image 68
Günter Zöchbauer Avatar answered Nov 02 '22 23:11

Günter Zöchbauer