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>