Angular Signals Introduction
Tags: angular, rxjs, signals, frontend
Published: 2023-04-22 23:45:57

In essence, a signal is a combination of a variable and a change notification. Unlike observables, signals are synchronous and always possess a value.

### 🎯 Working with signals

There are three distinct methods that can be used to manipulate signal values in Angular.

**set()** method allows for the replacement of a signal's current value with a new one.
```typescript
numb = signal(1);

numb.set(2);
```

**update()** method can be used to modify a signal's value based on its current value.
```typescript
name = signal('Dino');
name.update((value) => value + '1337') // Dino1337
```

**mutate()** method is used to modify the content of a signal value, without replacing the signal value itself. When working with arrays, you can use this method to modify individual array elements. Similarly, when working with objects, this method can be used to modify specific object properties.
```typescript
arr = signal([]);
arr.mutate((v) => v.push(i));

obj = signal({ name });
obj.mutate((v) => v.name = 'Dino');
```

#### Computed signals

I believe this is the strongest use case for basic work signals so far, and here is why:

```typescript
@Component({ 
  template: `
    {{ fullnameA }} // will not update
    {{ fullnameB() }} // will update

    <button (click)="changeSurname()">Change surname</button>
  `
})
export class App {
  nameA = 'John';
  surnameA = 'Doe';
  fullnameA = this.nameA + this.surnameA;

  nameB = signal('Jane');
  surnameB = signal('Doe');
  fullnameB = computed(() => this.nameB() + this.surnameB());

  changeSurname() {
    this.surnameA = 'Haaland';
    this.surnameB.set('Ibrahimovic');
  }
}
```

At first glance, many might assume that modifying the surnameA variable would automatically update the fullnameA variable, just as it would if we were using an Angular expression like `{{ nameA + surnameA }}`. However, this is not the case.

Using **signals** (computed signals), which automatically recalculate whenever any of their dependent signals change, we can achieve this.

But hey, of course this works! Signals are functions and we are binding to function call here. And we all know it's a golden rule not to do that.
We could as well do something like this:

```typescript
  {{ fullnameA() }}

  fullnameA = () => this.nameA + this.surnameA;
```

And that will work to... but!

![signal_cd_example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfkh565uzls8796hmrk3.gif)

This demonstrates that fullnameA() will be called whenever change detection is triggered, whereas signal fullnameB() will only be called when its dependent signal is updated. This feature is remarkable because using signals allows for more precise management of change detection, which can lead to better performance.

Moreover, computed signals are re-calculated under two conditions: when one or more of its dependent signals are altered, and when the value of the computed signal is read.

#### Using effect

Signal effect are pretty much useful for getting notified when your signal gets updated (changed), so you can log it or make API calls (_like you would be able to do with React's useEffect.. kinda_).

```typescript
effect(() => console.log(this.selected()));
effect(() => apiCall(this.param());
```

### 🎯 Summary

So far, my favorite feature has been computed signals, as explained earlier. Additionally, effects now offer a convenient way for us to watch and react to our signal updates.

Until then, I recommend trying to learn how both of these tools play together so you can pick best tool for the job in order to write more simple, readable and performant code.

I recommend this video from Josh Morony:
{% embed https://www.youtube.com/watch?v=4FkFmn0LmLI&t=149s&ab_channel=JoshuaMorony %}

As well as this video from Deborah Kurata:
{% embed https://www.youtube.com/watch?v=a6XKMj-WRhM&ab_channel=DeborahKurata %}

to check out possible comparisons between using signals vs observables.