Minha experiência para aprender Angular: onde estou agora?
Tags: wecoded, angular, typescript, frontend
Published: 2024-03-26 10:58:39

Olá! Que legal que você está aqui! 🤗
Em 2021 escrevi um artigo sobre minha experiência para aprender Angular que está disponível no Blog da [Zup](https://www.zup.com.br/) e que você pode ler [clicando aqui](https://www.zup.com.br/blog/aprender-angular) 👈.
Esse singelo texto é uma atualização do meu artigo. Quem está começando no Angular nesse momento provavelmente se deparou com mudanças importantes. A maior delas é que os módulos não existem mais (pelo menos a partir da versão 17)!

## Avisos!!! 🚨🚨

1. Esse artigo será um pouco longo, portanto se você não gosta de textos longos, cai fora!!!

2. Esse texto não foi gerado por inteligência artificial! Eu garanto! 😉

## Como assim sem módulos?!?!

No artigo anterior, expliquei que os componentes (que continuam sendo a base do Angular) precisavam ser colocados em módulos para que pudessem aparecer na tela. Inclusive podíamos criar outros módulos para serem usados no módulo principal. Agora que os módulos "desapareceram", é possível importar um componente diretamente em outro componente.

## O que?!?!

É isso mesmo que você leu! Os componentes, a partir de agora (quer dizer, começou na versão 15 em caráter de experimentação) são independentes (***standalone***)!

## Agora complicou tudo!!! 😫

Então vamos com muita calma.
Nas versões anteriores tínhamos a seguinte estrutura de arquivos dentro do componente principal (a pasta `app`):

![Antiga estrutura de arquivos do Angular](https://res.cloudinary.com/ananopaisdojavascript/image/upload/v1711200782/dev-to/l7lhjndxojsmpaij2tzz.png)

Essa estrutura também se modificou:

![Nova estrutura de arquivos do Angular](https://res.cloudinary.com/ananopaisdojavascript/image/upload/v1711200783/dev-to/elydf2fvg5wmwxn5b5fd.png)

Vejamos como ficou a estrutura do arquivo `app.component.ts`:

```ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  
}
```

Aqui aparecem todos os elementos do componente que comentei no artigo anterior (**selector**, **templateUrl**, **styleUrls**) e mais dois elementos novos: 

- `standalone: true` (Quer dizer que o componente é independente)
- `imports: []` (É o vetor que vai receber as importações)

No mais continua tudo igual, temos o decorador `@Component` e a classe que vai conter o comportamento do nosso componente.

## Nossa! Que legal!! Mas...

*... Eu ainda uso as versões anteriores. Como eu vou usar esse tipo de componente?!* 🧐

Se você usa as versões 15 ou 16, tem algumas alternativas:

1) Se você já está trabalhando em um projeto Angular que ainda tem `@NgModules`, será necessário fazer o seguinte:
- Apagar todos os arquivos que tem o nome `nome-do-arquivo.module.ts`.
- Mudar as estruturas dos arquivos `.ts` para a estrutura nova mostrada anteriormente.
- Criar componentes novos com o seguinte comando no terminal:

```
ng generate component nome-do-componente --standalone
```

Bem trabalhoso, não? 😣

2) Se você vai criar um projeto Angular do zero, use o seguinte comando no terminal:

```
ng new nome-do-projeto --standalone
```

O seu projeto vai nascer ***standalone***, sem necessidade de executar os passos anteriores (se você já usa a versão 17, não precisa fazer nada disso!).

## Vamos ao exemplo!!

No artigo anterior, usei um exemplo bem simples (um contador) para mostrar o funcionamento básico do Angular. Vou usar o mesmo contador para mostrar uma funcionalidade que tem dado o que falar: o ***signal***.

![Grupo de Kpop Twice cantando Signal](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExMGNsZ3EzMTFic2s1YjNoNnF6dGVycWtiMHFycGk1N3J5dTB6YW9lNyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/QslrOg2CAGBEm4pcra/giphy.gif)

*Mas não é esse "signal" aqui! (Entendedores e fãs de Twice entenderão!)* 😅 🍭

Um *signal* é uma função que reage à mudança de estado das informações.

## Socorro!! Não estou entendendo nada!! 😰

Quer fazer o favor de se acalmar?!?!?!
Antes de mergulhar no exemplo com o *signal*, devemos (tentar) entender em primeiro lugar o que é gerenciamento de estado e, para tal, vou usar um exemplo do mundo real: o estado da água.

Se você não faltou à aula de ciências (realmente espero que não!), aprendeu que a água pode passar por três estados: 

***Estado sólido***: é a água das geleiras, do pico das montanhas.
***Estado líquido***: é a água dos rios, lagos, mares e oceanos.
***Estado gasoso***: é a água que está na atmosfera.

![Estados da água](https://static.escolakids.uol.com.br/2020/08/estados-fisicos-da-agua.jpg)

E quais são os processos que fazem a água passar de um estado para outro?

***Fusão***: passagem do estado sólido para o líquido
***Vaporização***: passagem do estado líquido para o gasoso
***Solidificação***: passagem do estado líquido para o sólido
***Condensação***: passagem do estado gasoso para o líquido
***Sublimação***: passagem do estado sólido para o gasoso

![Mudanças dos estados da água](https://static.escolakids.uol.com.br/2020/08/mudancas-dos-estados-fisicos-da-agua.jpg)

Texto no qual retirei as informações:

[Estados físicos da água e suas mudanças (Escola Kids)](https://escolakids.uol.com.br/ciencias/estados-fisicos-da-agua-e-suas-mudancas.htm) 👈

## Como esse conceito se aplica dentro da programação?!

O estado é a condição atual de um aplicativo, que pode ser modificada ao longo do tempo.

## E como o conceito de estado pode ser usado no Angular?!?!

Com relação ao Angular, o estado refere-se aos dados e informações que são usados e compartilhados entre componentes, serviços e módulos do projeto. Sabemos que os componentes são a base de um projeto no Angular. Esses componentes precisam acessar e modificar os dados (e consequentemente o estado de uma parte do aplicativo). Nesse caso, o gerenciamento de estado fornece um modo organizado de lidar com esses dados, certificando-se de que estejam consistentes e acessíveis por todo o projeto. Os dados que podem ser armazenados, atualizados e lidos ficam em um local centralizado conhecido como contêiner de estado, que detém o estado do aplicativo e fornece métodos para interagir com ele. Essa centralização permite que vários componentes possam acessar e modificar os dados de modo previsível e consistente.

## Quais são as vantagens?!

- Compartilhamento de dados entre componentes com base nas interações do usuário
- Manuseio de estados complexos do aplicativo
- Fluxo de dados previsível
- Responsabilidades separadas

Voltando ao nosso exemplo do contador...

O componente está criado e a estrutura inicial é essa:

```ts
import { Component } from '@angular/core';

@Component({
  selector: 'counter',
  standalone: true,
  templateUrl: './counter.component.html',
  styleUrls: ['./counter.component.css'],
})
export class CounterComponent {
  
}
```

Agora vamos importar o contador *diretamente* no arquivo `app.component.ts`:

```ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CounterComponent } from './counter/counter.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, CounterComponent],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  
}

```

Nosso componente vai aparecer no HTML dessa forma:

```html
<counter />
```

Voltando ao arquivo `counter.component.ts`, vamos importar o *signal* para usar no nosso componente:

```ts
import { Component, signal } from '@angular/core';
```

Vamos definir uma função *signal* cujo valor (estado) inicial é 0:

```ts
value = signal(0);
```

Esse valor será mostrado no HTML da seguinte forma (não se esqueça de estamos lidando com uma função e precisa ser chamada como tal):

```html
<h2>{{ value() }}</h2>
```

Vamos criar dois botões para aumentar e diminuir o valor do contador:

```html
<button>Aumentar</button>
<button>Diminuir</button>
```

No arquivo `counter.component.ts`, vamos criar dois métodos para aumentar e diminuir o valor inicial. E é aqui que o *signal* se destaca! Ao clicar no botão de aumentar ou diminuir o *signal* avisa que o estado do valor configurado foi alterado pelos eventos de clique no botão.

*E como esse estado será alterado?* 🧐

O estado será alterado com `.set()` ou `.update()`

## Qual é a diferença?!

O `.set()` altera diretamente um valor, enquanto que o `.update()` usa uma função de *callback* para atualizar um valor.

```ts
// Exemplo com .set()
  increment() {
    this.value.set(this.value() + 1);
  }

  // Exemplo com .update()
  decrement() {
    this.value.update((num) => num - 1);
  }
```

Agora vamos usar esses métodos nos nossos botões

```html
<button (click)="increment()">Aumentar</button>
<button (click)="decrement()" [disabled]="value() === 0">Diminuir</button>
```

*No botão de diminuir coloquei uma condição para desabilitá-lo quando o valor voltasse ao estado inicial, que é 0*

Essa é a aparência final do nosso contador:

{% stackblitz https://stackblitz.com/edit/stackblitz-starters-wzlewo?embed=1&file=src%2Fapp%2Fcounter%2Fcounter.component.ts %}

## De 2021 até agora: onde estou?

Como havia dito no artigo anterior, bati a cabeça por muito tempo até entender os conceitos básicos do Angular. Ao estudar essas novas funcionalidades, tive a sensação de ter voltado à estaca zero, pois eu havia me acostumado com uma estrutura (com os módulos) e agora tenho que trabalhar com uma estrutura completamente diferente (sem os módulos)!

Tudo que foi explicado aqui está muito simplificado, porque:

1) Gostaria de ajudar quem está começando
2) Para que alguém possa passar por menos perrengues

Aprender Angular é um desafio que ainda vale a pena!!

Até a próxima! 🤗

## Referências 📚

Linkedin: [Techniques to manage state in angular and witch one we should use (Salem Naser)](https://www.linkedin.com/pulse/techniques-manage-state-angular-witch-one-we-should-use-salem-naser) 👈