Introduction to Signals in Angular

Introduction to Signals in Angular

What are signals ?

Signals contains a value , which when changed informs all the other consumers(subscribers) wherever the value is being used(listened) .

Value can be anything right from being a primitive to a complex data structure

There are two types of signals -

  1. Writable Signals
  2. Readonly Signals or Computed Signals

Writable Signals -

Writable signals can be created by using signal() with some initial value . It can be updated with by using .update() operation , based on previous value .

We can directly set a new value by using .set() operation .

Let's look an example where will create a writable signal which will hold some user related information called userInfo . We will create one more writable signal userAuthenticated which will store a boolean value whether user is authenticated or not .

Lets see how we can update and read those values from the signals


// creates a writable signal with value as 'true'
  userAuthenticated = signal(true);

  userInfo = signal({
    name : 'Omkar',
    loggedIn : true,
    permissions : ['READ','UPDATE'] 
  });



  showGreetingMessage(){
  
  // in order to read the value from signal 
    if(this.userAuthenticated()){
      console.log(`Welcome to application ${this.userInfo.name}`)
    } else {
      console.log('Please sign in to get more info')
    }
  }


  updatePermission(newPermission : string){
  
  // updating an existing signal value based on previous value 
    this.userInfo.update(userValue => {
      userValue.permissions.push(newPermission);
      return userValue;
    });
  }


    updateAuthetication(value : boolean){
    
    // setting new value to signal directly 
    this.userAuthenticated.set(value);
   }

Computed Signals

Computed signals are readonly signal which generates its value from other signals .

They can be generated by using computed function provided in @angular/core package .

In above example where we have created a function to show greeting message based on user authentication , now let's transform that function into a computed signals.

Previously it was written as -


  showGreetingMessage(){
  
  // in order to read the value from signal 
    if(this.userAuthenticated()){
      return `Welcome to application ${this.userInfo.name}`
    } else {
      return 'Please sign in to get more info'
    }
  }

After converting this function into computed signals , it would look something like this -


  showGreetingMessage = computed(() =>
    this.userAuthenticated()
      ? `Welcome to application ${this.userInfo.name}`
      : 'Please sign in to get more info'
  );

As you can see showGreetingMessage is a computed signal whose value depends on userAuthenticated . So whenever userAuthenticated is updated , angular knows it has to update showGreetingMessage

Can't set values directly to computed signals

You cannot use .set() method on computed signal to directly set a value for that particular signal . This will result in a compilation error

Computed signals are lazily loaded and memoized

When you read showGreetingMessage for the first time , only then it calculates its value and cache it . Thereafter whenever you read the signal value again , it returns the cache value .

It updates its cache value only when the signals from which the value is derived is changed . It recalculates itself and returns the updated value

Summary -

Writable Signals

  • Store any type of data (numbers, text, objects, arrays)
  • Values can be changed directly using .set() or .update()
  • Automatically notify listeners when values change

Computed Signals

  • Get their values from other signals
  • Values update automatically when source signals change
  • Cannot be modified directly
  • Smart performance features:
    • Only calculate when first needed (lazy loading)
    • Save results for reuse (memoization)
    • Recalculate only when source signals change