DEV Community

Dhananjay Kumar
Dhananjay Kumar

Posted on

What is the purpose of the Second Parameter in creating an Angular Signal

The angular signal() function creates a signal. This function takes two input parameters.

Initial value
Optional Equality function.
By default, Angular executes the code of effect() even if the signal is set or updated with the same value. How can we avoid that?

By leveraging the second parameter of the signal() function.

Image description

Let us first understand the problem statement through an example.

Angular provides the signal function to create a signal. You can create a signal as shown next,



product : IProduct = {
    Id:  "1",
    Title:"Pen",
    inStock: true,
    Price : 100

  }
  Product$ = signal<IProduct>(this.product);


Enter fullscreen mode Exit fullscreen mode

You can use the Product$ signal by calling it a function on the template.



<h2>{{Product$() | json}}</h2>
<button (click)="setProduct()">Set Products</button>


Enter fullscreen mode Exit fullscreen mode

An angular signal provides a set method to replace its value with the new value. This method removes the older value and sets the new value in the signal. In the setProduct function, update the signal with a new value as shown below,



setProduct(){
   let p : IProduct = 
      {
        Id:"1",
        Title:"Pen",
        Price: 300,
        inStock: true
      }; 
    this.Product$.set(p);
  }


Enter fullscreen mode Exit fullscreen mode

As you see, calling the setProduct function sets the signal with the same product each time.

Angular Signal has another concept called Effect. Angular calls the effect() function each time the signal changes or emits a new value. So let us say you need to run a set of code; when the signal changes, you put that code in effect.



  productEffect = effect(()=>{
     console.log('effect called'); 
     console.log(this.Product$());
  });


Enter fullscreen mode Exit fullscreen mode

In the productEffect effect(), we are printing the value of the Product$ signal. You may observe that,

  • Each time you click the button, the signal changes and is set with the same product.
  • It is the same product set to the signal, but the signal emits it.
  • Each time you click the button, the code in effect() is executed even though the signal emits the same product value.

Each time you click the button, the code in effect() is executed even though the signal emits the same product value. THIS IS THE PROBLEM, and it can be fixed by passing a second parameter in the signal function() while creating the signal.

The signal function takes two input parameters,

  1. Initial value
  2. Optional Equality function.

The signal function is declared as below,



export declare function signal<T>(initialValue: T, options?: CreateSignalOptions<T>): WritableSignal<T>;


Enter fullscreen mode Exit fullscreen mode

As you see that you can pass the options. The type of options is CreateSignalOptions, which is defined below,



export declare interface CreateSignalOptions<T> {
    /**
     * A comparison function which defines equality for signal values.
     */
    equal?: ValueEqualityFn<T>;
}


Enter fullscreen mode Exit fullscreen mode

The CreateSignalOptions has a method named equal. You can pass this equal function as the second parameter. The function can write logic to determine when the signal notifies and emits.

You can create the equal function as shown in the following code block:



function signalEquality(a:IProduct, b: IProduct) {
  console.log("hello") // it executes each time
  if(JSON.stringify(a)=== JSON.stringify(b)){
    return true;
  }
  return false; 
}


Enter fullscreen mode Exit fullscreen mode

You can pass the above function as the value of the equal function while creating the signal.



 Product$ = signal<IProduct>(this.product,{equal:signalEquality});



Enter fullscreen mode Exit fullscreen mode

Now each time you click the button, the code in effect() is only executed when the signal() is set with a new value and emitting it.

I hope you understand the purpose of the second parameter in creating a signal in Angular. Thanks for reading.

Top comments (0)