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!