Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does angular2 detect the changes in a stateful pipe?

I created a simple stateful pipe based on the Angular.io tutorial on pipes:

@Pipe({
    name: 'fetch',
    pure: false
})

class FetchJsonPipe  implements PipeTransform{
    private fetchedValue = 'waiting';
    private fetchedValue2 = 'waiting2';

    transform(value:string, args:string[]):any {
        setTimeout(() => {
            this.fetchedValue = 'done';
            this.fetchedValue2 = 'done2';
        }, 3000);
        return this.fetchedValue2;
    }
}

@Component({ selector: 'sd-splash'
           , template: 'hello ng2 {{ "5" | fetch }}'
           , pipes: [FetchJsonPipe]
           })

My question is, I return this.fetchedValue from #transform immediately. Since it's just a string, it's returned by value. Later, when the timeout is finished, I just assign the value 'done' to a property (which is also private).

How does Angular2 know that the intial result, 'waiting' is not final? How does it know that the updated value will be available through #fetchedValue? The promise is not exposed at all, and Angular2 has no information on the name of the field I store the result in.

The only clue it has is pure == false, which I guess instructs it to watch the instance for changes. But I don't see how it has information on which field to watch.

But it works! And I have no idea why.

Cheers

like image 571
sevcsik Avatar asked Feb 08 '23 02:02

sevcsik


1 Answers

Angular monkey patches browser events (including setTimeout()) using a library called Zone.js. When events happen, AngularJS triggers change detection.

With stateful pipes, AngularJS will re-evaluate the pipe on every event because the pipe result may change even with the same inputs.

With pure pipes, AngularJS will trigger change detection and re-evaluate the pipe only when one of the input changes (i.e. data coming in, or the args).

like image 88
pixelbits Avatar answered Feb 10 '23 14:02

pixelbits