javascriptangulartypescriptsignalsangular-signals

Why is my signal not updating the UI when using `++` or `--` operation


I have this scenario, where I want to increment/decrement two values, so I use the standard ++ and -- operation to do this inside the update method of signals.

import { Component, signal } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-root',
  template: `
    <hr/>
    {{id()}}
    <hr/>
    {{num()}}
  `,
})
export class App {
  id = signal(1);
  num = signal(1000);

  ngOnInit() {
    setInterval(() => {
      this.id.update((prev: number) => prev++);
      this.num.update((prev: number) => prev--);
    }, 2000);
  }
}
bootstrapApplication(App);

Why are my signals updated, when I clearly incremented them.

Stackblitz Replication


Solution

  • I found the answer in the below link:

    Postfix and prefix increments in JavaScript

    If used postfix, with operator after operand (for example, x++), then it returns the value before incrementing.


    If used postfix, with operator after operand (for example, ++x), then it returns the value after incrementing.

    Since you are using postfix instead of prefix, so the value that is returned after the update callback runs, is the original value.

    Since signals, trigger change only when the actual value has changed ( in your case the original value gets returned without increment), the update does not happen.

    The most simplest way is to just increment it manually, so that all developers grasp it easily, getting rid of the understanding complexity of postfix and prefix.

    Just change it to prefix as shown below (Commented) or go for the simpler method of explicitly incrementing the value.

    import { Component, signal } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    
    @Component({
      selector: 'app-root',
      template: `
        <hr/>
        {{id()}}
        <hr/>
        {{num()}}
      `,
    })
    export class App {
      id = signal(1);
      num = signal(1000);
    
      ngOnInit() {
        setInterval(() => {
          // this.id.update((prev: number) => ++prev); // <- prefix
          // this.num.update((prev: number) => --prev); // <- prefix
          // simpler solution
          this.id.update((prev: number) => prev + 1);
          this.num.update((prev: number) => prev - 1);
        }, 2000);
      }
    }
    bootstrapApplication(App);
    

    Stackblitz Demo