Implementing and Understanding Writable Angular Signals with a Practical Case Example
Tags: angular, frontend, webdev, signals
Published: 2023-06-29 14:25:41

Hey folks, how are you today?! I hope you're fine 😄

Today in this article I would like to talk and share about the famous **Angular Signals**! You've probably heard about it and how it can be useful!

I'll talk a little about **Angular Signals** and talk about the **Writable Signals** type with a practical example! And in another Post we will talk about **Computed Signals** and **Effects**!

I believe that if we divide the subject and go through each piece calmly, we can better understand how it works and gradually improve!

Sooo...

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0yar057kpofe7o61xs5m.gif)
___
## 🧩 What is Angular Signals?!

Angular Signals was a big step taken by Angular and the community being available in version 16 and significantly changing the way we can work with reactivism in our applications in a simpler way!

In my mind I put together a small illustration to bring Signals to the real world. It's like I had a secret and when the secret changed I would let people know who were interested and who were consuming the secret that it changed and according to the changes made each person would do something about the secret!

That's secret (**value**) can be a simply secret (**primitive value**) or a really big secret (**complex data structure**).
___

## 🧩 A little more about

Signals in my opinion has 3 great features that we need to have a good understanding of each one in order to get the best out of it!

They are: **Writable Signals**, **Computed Signals** and **Effects**!
___

## 🧩 Writable Signals

With **Writable Signals** we can use an API and with that we can use some interesting features offered by the API to manipulate the value (or the secret like the example above in the description) like `.set()`, ` .update() ` and `.mutate()` and in this article we'll talk about each of them with interactive examples.

###📍 Creating the Signal

To create it, we just need to declare a new variable calling the `.signal()` function with an initial value, as shown below:

```typescript
import { signal } from '@angular/core';

export class App {

  yourSignalVariable = signal(yourSignalValue);
}
```

###📍 Changing the signal with .set():

With the **Writable** signal type we can change the signal value calling the `.set()` directly and passing the new value, like below:

```typescript
import { signal } from '@angular/core';
...

userIsLogged = signal(false);

makeLogin(): void {
  this.userIsLogged.set(true);
}

makeLogout(): void {
  this.userIsLogged.set(false);
}
```

As you can see with it we just pass the values ​​directly and that's it!

###📍 Changing the signal with .update():

We can also call `.update()` directly to update the value when we want to make not very simple changes to the value, like a calculation or a string change, for example! Below you can see a simple example:

```typescript
import { signal } from '@angular/core';
...

userPassword = signal('secret');

insertUserPasswordEncryption(): void {
  this.userPassword.update(
    (value) => (value = `${value}-passwordEncryption`)
  );
}
```

###📍 Changing the signal with .mutate():

When we work with complex data structure like an object, array and we want to make some changes it can be useful to work with and more recommended to use `.mutate()` to do that, below we can see:

```typescript
import { signal } from '@angular/core';
...

citiesIWantToVisit = signal([
  {
    name: 'Phoenix',
    visited: false,
  },
  {
    name: 'New York',
    visited: false,
  },
]);

updateCitiesStatus(): void {
  this.citiesIWantToVisit.mutate((cities) => {
    cities.forEach((city) => {
      if (city.name != 'Phoenix') return;

      city.visited = true;
    });
  });
}
```

So basically when we call `.mutate()` we are telling Signal to update its value and it gets a callback to change the value and keep the reference. **Signal.set()** just accepts a value directly to change the reference, while **Signal.mutate()** takes a callback to change the value and keep the reference.
___

## 🧩 Live example:

Below you can see the example with all the possible variations that we have when we use **Signals** of the **Writable** type and you can also interact with the buttons to see the transformation!

{% embed https://stackblitz.com/edit/stackblitz-starters-echron?file=src%2Fmain.ts %}

Directly link: [Stackblitz Link](https://stackblitz.com/edit/stackblitz-starters-echron?file=src%2Fmain.ts)
___

That's all, folks!

**Signals** are powerful and useful when we want to work with reactivism in our application and I imagine that it will evolve more and more and become more powerful!

In the next article we'll talk about **Computed Signals** and see more about **Signals**!

I hope you enjoyed and maybe with this you can understand a little better about **Signals** ! if you have questions, suggestions or anything else please leave a comment!

See you soon 🤟💪🤟💪