Olá Marcus! Tudo bem contigo?
Entendo a situação que você enfrentou ao lidar com a API do Google e agradeço por compartilhar sua sugestão para resolver o problema de erro 400 e travamento da aplicação. Vamos analisar a alteração que você fez e algumas possíveis melhorias.
Na sua alteração, você modificou o método buscar no arquivo livro.service.ts, incluindo um retorno de null quando o parâmetro valorDigitado é vazio. Essa é uma abordagem válida para evitar o erro 400 quando o campo de busca está vazio. Aqui está o trecho de código modificado:
buscar(valorDigitado: string): Observable<Item[] | null> {
if (valorDigitado) {
const params = new HttpParams().append('q', valorDigitado);
return this.http.get<LivrosResultado>(this.API, { params }).pipe(
map(retorno => { return retorno.items; })
);
} else {
return of(null);
}
}
No componente lista-livros.component.ts, você utiliza o FormControl chamado campoBusca para monitorar as mudanças do valor digitado e buscar os livros correspondentes. A observação feita na função ngOnInit() é que, ao receber null na resposta do serviço, você também retorna null. Isso é uma boa prática para evitar erros ao manipular os resultados. Aqui está o trecho de código modificado:
campoBusca = new FormControl();
livrosEncontrados$: Observable<Livro[] | null>;
constructor(private service: LivroService) { }
ngOnInit(): void {
this.livrosEncontrados$ = this.campoBusca.valueChanges.pipe(
switchMap((valorDigitado) => { return this.service.buscar(valorDigitado) }),
map((items) => {
if (items) {
return this.livrosResultadoParaLivros(items);
} else {
return null;
}
})
);
}
Sua abordagem parece ser funcional, no entanto, considerando que o curso é sobre "RxJS e Angular: programando de forma reativa", podemos otimizar ainda mais a busca usando os recursos do RxJS. Em vez de retornar null, podemos utilizar o operador filter para garantir que a busca só ocorra quando o valor digitado for válido. Além disso, podemos tratar os erros para evitar que a aplicação trave. Vou mostrar essas melhorias no código abaixo:
Em livro.service.ts, vamos ajustar a função buscar:
import { catchError, filter } from 'rxjs/operators';
buscar(valorDigitado: string): Observable<Item[]> {
if (valorDigitado) {
const params = new HttpParams().append('q', valorDigitado);
return this.http.get<LivrosResultado>(this.API, { params }).pipe(
map(retorno => { return retorno.items; }),
catchError(error => {
// Trate o erro de acordo com a sua necessidade, por exemplo:
console.error('Erro na busca:', error);
return of([]);
})
);
} else {
return of([]);
}
}
E no componente lista-livros.component.ts, vamos fazer a busca somente quando o valor digitado for válido:
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
campoBusca = new FormControl();
livrosEncontrados$: Observable<Livro[]>;
constructor(private service: LivroService) { }
ngOnInit(): void {
this.livrosEncontrados$ = this.campoBusca.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged(),
filter(valorDigitado => !!valorDigitado), // Filtro para buscar apenas quando o valor for válido
switchMap((valorDigitado) => this.service.buscar(valorDigitado))
);
}
Com essas alterações, melhoramos a busca reativa e tratamos possíveis erros na solicitação HTTP. Utilizamos os operadores debounceTime, distinctUntilChanged e filter para controlar as solicitações à API e evitar chamadas desnecessárias quando o usuário estiver digitando rapidamente.
Espero ter ajudado! Se tiver mais dúvidas ou precisar de mais esclarecimentos, fique à vontade para perguntar.
Abraços e bons estudos!