Display Name
Display Name

Reputation: 15081

Why does Angular produce 3 rather than 1 in the following simple code?

Why is the output 3 rather than 1 in the following code?

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {

   i: number =0;  

  get count(): number{
    this.i++;
    return this.i;
  }
}

app.component.html:

<h1>{{count}}</h1>

The rendered output on the browser is 3.

Upvotes: 0

Views: 61

Answers (3)

sp814610
sp814610

Reputation: 36

It is because of Angular's Change Detection mechanism.

Multiple change detection cycles are performed, and for each of them the getter for the 'count' property is called.

Since the getter for the 'count' property contains the instruction to increment the value of property 'i', the value will be incremented at each change detection cycle.

Upvotes: 1

peinearydevelopment
peinearydevelopment

Reputation: 11474

This is a larger question dealing with how Angular handles change detection.

If you update your component as follows(specifying the OnPush ChangeDetectionStrategy), then you will see the expected value of 1.

    import { Component, ChangeDetectionStrategy } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class AppComponent {
    
       i: number =0;  
    
      get count(): number{
        this.i++;
        return this.i;
      }
    }

You can read more about this enum and the related topics on Angular's docs:

Stackblitz example

Upvotes: 1

TotallyNewb
TotallyNewb

Reputation: 4790

This is because TypeScript is compiled into javascript, and in js there is no notion of "getter" - there are objects and functions.

So, what you're doing is using a function in a template. And since angular can't know what could change the value returned by the function, it's evaluated on every change detection cycle that affects the component. So, in your case - there were 3 change detection cycles ran before your app fully rendered.

Caveat is - don't use functions to bind values in templates unless you're using the OnPush change detection strategy (and even then double-think if you REALLY need to use a function and are aware of possible 'gotchas').

On a sidenote - using a getter with a side-effect affecting the returned value is probably a no-go in any language, but I assume it was only to illustrate your issue.

Upvotes: 4

Related Questions