A diretiva ngIf
é muito útil para situações comuns no dia a dia do programador…
Mas criar e remover elementos é apenas a ponta do Iceberg e há mais no ngif
do que aparenta.
A escrita do ngIf
junto com o pipe async
é essencial, no seu Arsenal de Programador, para você desenvolver uma aplicação mais reativa e deixar seu Código Épico!
Então continue lendo esse artigo para deixar seu código:
- Mais limpo;
- Mais reativo;
- E menos vulnerável a erros.
O que é o Angular Async Pipe?
O Angular async
pipe serve para fazer a saída de um valor na página, mesmo que o valor demore um pouco a ser atribuído na variável.
Então o async
é muito útil quando você precisa fazer chamadas ao servidor e vai demorar alguns segundos para retornar o valor.
Para isso vamos ver um exemplo de chamada ao servidor com o async
. (usando o modulo Angular HttpClient
)
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
//...
export class UserComponent {
user$: Observable<any>;
constructor(private http: HttpClient) { }
ngOnInit() {
this.user$ = this.http.get<any>('/user/1'); //requisita o usuário de id=1.
}
}
A função http
retorna um observable muito simples…
E para exibir o seu valor, você referencia a variável observable junto com o async
:
{{ user$ | async }}
O sufixo do dólar ( $ ) é usado para indicar uma fonte observable. Assim nem você, ou sua possível equipe, confunde com uma variável “normal”.
Mas porque ter o trabalho de usar o Pipe Async?
Agora vamos dar uma olhada em como ficaria o exemplo a cima sem o pipe:
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subscription } from 'rxjs';
//...
export class UserComponent {
user$: Observable<any>;
userSubscription: Subscription;
user: any;
constructor(private http: HttpClient) { }
ngOnInit() {
this.user$ = this.http.get<any>('/user/1');
this.userSubscription = this.user$
.subscribe(user => this.user = user); //Assina o Observable.
}
ngOnDestroy() {
this.userSubscription.unsubscribe(); //Cancela a assinatura do Observable.
}
}
{{ user }}
A função http
ainda retorna um observable, mas para fazer o valor recebido pelo servidor aparecer na tela, você precisa:
- Assinar o observable;
- Passar o valor recebido para uma variável do componente;
- Cancelar a assinatura do observable.
Só depois “joga” o valor no template.
Tudo porque se você assina o observável manualmente, também precisa cancelar a assinatura manualmente.
Caso contrário você corre o risco de vazamento de memória quando o componente é destruído.
Porém essa escrita adicional é desnecessária com o uso do async
, pois ele próprio cuida de assinar e cancelar assinatura do observable.
E assim o código não fica muito mais limpo e bonito?
Usando o ngIf com o Angular Async Pipe
Claro, a interpolação ( chaves duplas {{ }}
) não é o único uso que o async
possui.
Você também pode aplicar o pipe junto com a diretiva ngIf
para aproveitar todos os seus benefícios:
<div *ngIf="user$ | async">
{{ (user$ | async)?.name }}
</div>
Ao invés de inserir uma variável no ngIf
, você utiliza o observable como valor condicional.
Assim o código do componente fica mais limpo que a xícara de café no final do expediente.
Porém tem 2 problemas no exemplo acima…
Primeiro o async
apareceu 2 vezes. O que significa 2 assinaturas no mesmo observable. (um desperdício na minha opinião)
Segundo não sei se você concorda, mas escrever (user$ | async)?.name
fica feio para caramba!
Mas tem solução ao empregar a sintaxe do “as”.
O operador elvis ( ? ) em (user$ | async)?.name serve para acessar com segurança a propriedade de um objeto. Assim caso ocorra um erro no objeto, a aplicação funciona sem maiores problemas.
Como utilizar o NgIf com “as” Async
Ao acrescentar o “as” a combinação de ngIf
com async
, você atribui o valor do objeto, recebido pelo observable user$
, a uma variável local:
<div *ngIf="user$ | async as user">
{{ user.name }}
</div>
Assim o resultado da expressão user$ | async
é vinculado ao valor de user
. (sem sufixo de $
, pois não é um observable)
Note também que você pode utilizar a variável user
em qualquer lugar dentro do ngIf
, mas nunca fora. (é parecido com um escopo de função)
Por fim a sintaxe ngIf + async + "as"
, fornece para você maior flexibilidade para implementar o “else”:
<div *ngIf="(user$ | async) as user; else loading">
{{ user.name }}
</div>
<ng-template #loading>
Carregando usuário...
</ng-template>
Saiba mais sobre a escrita do ngIf junto com “else” neste artigo.
Agora você tem mais um recurso para o seu Arsenal de Programador.
E caso tenha gostado desse artigo, ou tem alguma dúvida, não esqueça de deixar nos comentários abaixo:
Hey,
o que você achou deste conteúdo? Conte nos comentários.
Boa noite, o observable tem o next, error e complete, utilizando desta forma, como eu conseguiria pegar o error e mostrar na tela? Obrigada. Sou iniciante no angular, estou me virando para aprender.. rs
Opa, boa noite! ;D
Essas 3 coisas (next, error, complete) pertencem a função
subscribe()
do objeto Observable, mas ela é apenas uma das funções disponíveis.No caso que você descreveu, seria necessário usar a função
Observable.pipe()
. Ela serve para encadear várias “operações / atividades” que você deseja realizar.Sendo uma dessas “operações” disponíveis, a captura de erro.
Acredito que essa breve explicação não deve ter fornecido uma visão muita prática. haha
Por isso, irei deixar o link de uma aula da Loiane Groner, onde ela mostra (de forma prática) o que fazer nesse caso: link da aula aqui
Referências:
Angular DOC
Angular University
Ultimate Courses
Malcoded