Angular: Subjects
Antes de começar a falar sobre subjects, precisamos passar por Observable e Subscribe. Bom, para quem já está trabalhando com Angular a algum tempo, já conhece o Observable. Agora, para aqueles que estão tendo o seu primeiro contato, segue uma breve descrição sobre Observable retirada do site tablelles:
Por definição é uma coleção que funciona de forma unidirecional, ou seja, ele emite notificações sempre que ocorre uma mudança em um de seus itens e a partir disso podemos executar uma ação. Digamos que ele resolve o mesmo problema que a versão anterior do Angular havia resolvido com o $watch, porém sem usar força bruta. Enquanto no $watch verificamos todo nosso escopo por alterações após cada $digest cycle (o que tem um grande custo na performance), com Observable esta verificação não acontece, pois para cada evento é emitida uma notificação para nosso Observable e então tratamos os dados.
Em outras palavras, o observable permite você fazer um subscribe em um método ou função para que possa receber as suas modificações. Para facilitar o seu entendimento, veja o exemplo abaixo:
@Injectable()
class NewsService {
...
getNews(): Observable<News[]> {
return this.http.get('sua API')
.map(res=>res.json())
.catch(err=> Observable.throw(err.message));
}
...
}
O trecho de código acima está bem simples, ele está buscando um lista de noticias e retornando ela no formato .json(). Para acessar o retorno desse método, você precisa fazer um subscribe nele. Seguindo o exemplo de news, veja abaixo o exemplo de um componente fazendo o subscribe em getNews()
.
import { NewsService } from './services/news.service';
@Component({
/* Propriedades do componente*/
})
class NewsComponent {
...
constructor(private newsService: NewsService){}
private news: News[];
getNews() {
this.newsService.getNews()
.subscribe(
news => this.news = news,
error => /* Tratamos os erros aqui :) */);
}
...
}
No exemplo acima, nós estamos chamando a função getNews()
e dando um subscribe no seu retorno, assim que a resposta vier e for transformada em JSON, seremos notificados e o array news receberá a lista de notícias, ou caso ocorra algum erro no seu retorno, você pode tratar criando um método que notifique o seu usuário em error => seu método().
Bom, depois desse overview sobre Observable e subscribe, vamos entrar no tópico desse artigo o Subject.
Imagine o seguinte cenário: você precisa enviar algo para getNews()
, mas não precisa fazer uma outra requisição a um WS (WEB Service) para receber esse retorno. Para esse tipo de situação nós podemos utilizar o Subject.
O subject permite fazer um subscribe e um publish, em outras palavras, ele nos permite enviar e receber dados. Para ficar mais claro, vamos criar um novo projeto e um exemplo utilizando o subject com o Angular Cli. Para isso, siga os passos abaixo:
Abra o seu terminal e execute o seguinte comando:
ng new angular-subject
O comando acima irá criar um novo projeto chamado angular-subject
.
Para os próximos passos, você irá precisar de uma IDE, eu irei utilizar o VS Code, mas você pode utilizar uma de sua preferência. Abra o seu projeto e atualize o arquivo app.component.html com o seguinte trecho de código:
<div *ngIf="message">
{{message}}
</div>
<app-home>
</app-home>
O próximo passo será criar um novo componente chamado HomCompenent. Para isso, execute o comando abaixo no seu terminal:
ng g c components/home
Depois que o comando acima finalizar, atualize o seu arquivo home.component.html com o seguinte trecho de código:
<input type="text" placeholder="Enter message" #message>
<button type="button" (click)="setMessage(message)" >Send message</button>
Note que no trecho de código acima estamos criando uma variável chamada #message e um método recebendo ela. Nos próximos passos nós iremos utilizar ela para enviar uma notificação.
Agora crie um novo serviço chamado MessageService,
para gerenciar as suas notificações. Para isso, execute o seguinte comando no seu terminal:
ng g s service/message
O comando acima irá criar um novo arquivo chamado message.service.ts, no seguinte path: src\app\service\message.service.ts. Atualize ele com o trecho de código abaixo:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
public message = new Subject<string>();
setMessage(value: string) {
this.message.next(value);
}
}
Agora injete o serviço MessageService
em HomeComponen
:
import { Component } from '@angular/core';
import { MessageService } from '../../service/message.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent {
constructor(public messageService:MessageService) { }
setMessage(event) {
console.log(event.value);
this.messageService.setMessage(event.value);
}
}
Para testar o código desenvolvido nos passos anteriores, execute o comando abaixo no seu terminal:
ng serve
O comando irá abrir no seu navegador o seguinte endereço: http://localhost:4200/. Abaixo você tem uma imagem demonstrando esse passo:

Agora quando você enviar qualquer valor para variável #message
dehome.component.html
ela irá exibir esse valor em {{message}}
que está em app.component.html.
Com isso finalizamos esse artigo, caso tenha interesse em baixar o projeto desenvolvido aqui, segue o seu link no GitHub: Angular-Subject.