material-de-estudos

Pipe do RXJS e Resgatando dados através de parâmetros de rota

Sumário

RXJS Pipe

Um Pipe do RXJS Ă© diferente do Pipe do Angular

O RxJs disponibiliza operadores para trabalhar com os Observables de forma declarativa e clara. Sendo operadores, funções. Há dois tipos de operadores:

import { of, map } from 'rxjs';
of(1, 2, 3)
  .pipe(map((x) => x * x))
  .subscribe((v) => console.log(`value: ${v}`));

Piping

Observables têm o método .pipe() para facilitar a clareza na leitura durante a transformação dos dados do Observable. Ele transforma os dados emitidos por um Observable antes de dar ao Observador (subscribe)

É possível usar o método tap para side-effects para notificar e monitorar as mudanças do Observable fonte

Exemplo de uso no Angular:

constructor() {
  of('banana', 'pitaia', 'pera', 'maçã')
    .pipe(
      map((fruta) => fruta.toUpperCase()),
      filter((fruta) => fruta.startsWith('B') || fruta.startsWith('M')),
      tap(console.log)
    )
    .subscribe((result) => {
      this.frutas.push(result);
    });
}

Resultado:

Resultado do CĂłdigo do Observable com Piping

Uma boa prática para os Observables, é sufixar a variável com o símbolo de dólar ($) para indicar os Observables:

import { filter, map, of, tap } from 'rxjs';

frutas$ = of('banana', 'pitaia', 'pera', 'maçã');

constructor() {
  this.frutas$
    .pipe(
      map((fruta) => fruta.toUpperCase()),
      filter((fruta) => fruta.startsWith('B') || fruta.startsWith('M')),
      tap(console.log)
    )
    .subscribe((result) => {
      this.frutas.push(result);
    });
}

Também é possível combinar Observables, por exemplo quando for chamar duas APIs concorrentemente (ao mesmo tempo), e retornar apenas uma informação ao usuário.

Resgatando dados pelo URL através do parâmetro de rota

const routes: Routes = [
  { path: '', redirectTo: 'list', pathMatch: 'full' },
  { path: 'list', component: ListingComponent },
  { path: 'new', component: RegisterComponent },
  { path: 'edit/:id', component: RegisterComponent },
];
export class ProductService {
  private baseApiUrl = 'http://localhost:3000/';

  constructor(private http: HttpClient) {}

  getProducts(): Observable<ProductList> {
    return this.http.get<ProductList>(`${this.baseApiUrl}products`);
  }

  // novo método para resgatar o produto pelo Id
  getProductById(id: string): Observable<Product> {
    return this.http.get<Product>(`${this.baseApiUrl}products/${id}`);
  }
}
export class RegisterComponent implements OnInit {
  id!: string;
  product!: Product;

  constructor(
    private ProductService: ProductService,
    private activatedRoute: ActivatedRoute
  ) {}

  ngOnInit(): void {
    // pegar o id do produto em uma url: [//http](http://localhost:4200/product/edit/1)
    // sendo o '/product', o url raiz
    this.id = this.activatedRoute.snapshot.url[1].path;

    this.ProductService.getProductById(this.id).subscribe(
      (product: Product) => (this.product = product)
    );
  }
}