Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Sugestão] Solução para quem estava com problemas no uso do distinctUntilChanged()

Caso alguém esteja com problemas na utilização do operador distinctUntilChanged() do RXJS segue abaixo código com solução que encontrei. Aparentemente ao tiparmos as arrow functions o erro "Error: src/app/views/lista-livros/lista-livros.component.html:20:26 - error TS2322: Type 'unknown' is not assignable to type 'NgIterable'." desaparece.

lista-livros.component.ts

import { LivrosResultado } from './../../models/interfaces';
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { catchError, debounceTime, distinctUntilChanged, filter, map, Observable, switchMap, tap, throwError } from 'rxjs';
import { Item } from 'src/app/models/interfaces';
import { LivroVolumeInfo } from 'src/app/models/livroVolumeInfo';
import { LivroService } from 'src/app/service/livro.service';

const PAUSA = 300;
@Component({
  selector: 'app-lista-livros',
  templateUrl: './lista-livros.component.html',
  styleUrls: ['./lista-livros.component.css']
})
export class ListaLivrosComponent {

  campoBusca = new FormControl();
  mensagemErro = '';
  livrosResultado: LivrosResultado;

  constructor(private service: LivroService) { }

  livrosEncontrados$: Observable<LivroVolumeInfo[]> = this.campoBusca.valueChanges
    .pipe(
      debounceTime(PAUSA),
      filter((valorDigitado) => valorDigitado.length >= 3),
      tap(() => console.log('Fluxo inicial')),
      distinctUntilChanged(),
      switchMap((valorDigitado) => this.service.buscar(valorDigitado)),
      tap(console.log),
      map((resultado: LivrosResultado) => {
        this.livrosResultado = resultado;
        return resultado.items ?? [];
      }),
      map((items: Item[]) => this.livrosResultadoParaLivros(items)),
      catchError(() => throwError(() => new Error(this.mensagemErro = `Ops, ocorreu um erro! Recarregue a aplicação!`)))
    );

  livrosResultadoParaLivros(items: Item[]): LivroVolumeInfo[] {
    return items.map(item => new LivroVolumeInfo(item));
  }
}

lista-livros.component.html

<section class="container">
  <header>Que livro você procura?</header>
  <div class="busca">
    <input
      type="search"
      [formControl]="campoBusca"
    >
    <button>
      <img src="assets/imagens/icone-busca.png" alt="Lupa de cor roxa">
    </button>
  </div>
  <p>Busque por assunto, autoria, nome...</p>
  <div class="resultados mensagem-erro" *ngIf="mensagemErro">
    {{ mensagemErro }}
  </div>
  <div class="resultados" *ngIf="livrosEncontrados$ | async">
    {{ livrosResultado.totalItems }} resultados encontrados.
  </div>
<div class="container-card" *ngIf="livrosEncontrados$ | async as listaLivros, else telaInicial">
  <div *ngFor="let livro of listaLivros">
    <app-livro [livro]="livro"></app-livro>
  </div>
</div>
<ng-template #telaInicial>
  <div class="imagens">
    <h1 class="titulo">Busque o livro <br> que quiser na <br> nossa estante!</h1>
    <img
      class="ilustracao"
      src="../../assets/imagens/ilustracao-estante.png"
      alt="Ilustração de uma pessoa em pé ao lado de uma estante com livros e plantas">
  </div>
</ng-template>
1 resposta
solução!

Olá, Lorenzo, como vai?

Que incrível a sua iniciativa de compartilhar a solução aqui no fórum! Além de demonstrar seu comprometimento com o aprendizado, atitudes como essa ajudam muito a comunidade. A tipagem das funções realmente é uma ótima prática para evitar erros como o que você mencionou.

Continue contribuindo e explorando! O fórum está sempre à disposição para trocar ideias e resolver dúvidas.

Siga firme nos seus estudos!

Abraços :)