Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Paginação

Olá, professora. Ainda neste curso, haveria a possibilidade de você inserir uma paginação nesta aplicação? Senti falta disso e fiquei curioso sobre como você faria. Se possível, seria de grande agrado se você pudesse incluir mais um vídeo sobre isso no curso.

Desde já, o curso está incrível. Obrigado!

2 respostas
solução!

Oi, Marco, tudo bem?

Fico feliz que esteja gostando do curso! Entendo perfeitamente o seu interesse em adicionar paginação à aplicação, pois é um recurso muito útil e comum em projetos reais. Vamos juntos implementar sua sugestão no projeto seguindo as modificações de código abaixo.

Para isso precisamos alterar três arquivos, o livro.service.ts, lista-livreo.component.html e lista-livro.component.ts. O código completo para cada um deles está descrito abaixo:

  • livro.service.ts:
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { LivrosResultado } from '../models/interfaces';

@Injectable({
  providedIn: 'root'
})
export class LivroService {

  private readonly API = 'https://www.googleapis.com/books/v1/volumes';
  constructor(private http: HttpClient) { }

  buscar(valorDigitado: string, startIndex: number = 0, maxResults: number = 10): Observable<LivrosResultado> {
    const params = new HttpParams()
      .append('q', valorDigitado)
      .append('startIndex', startIndex.toString())
      .append('maxResults', maxResults.toString());
    return this.http.get<LivrosResultado>(this.API, { params });
  }
}
  • lista-livro.component.ts:
import { switchMap, map, tap, filter, debounceTime, throwError, catchError, EMPTY, of, BehaviorSubject, combineLatest } from 'rxjs';
import { Component } from '@angular/core';
import { LivroService } from 'src/app/service/livro.service';
import { Item, LivrosResultado } from 'src/app/models/interfaces';
import { LivroVolumeInfo } from 'src/app/models/livroVolumeInfo';
import { FormControl } from '@angular/forms';

const PAUSA = 300;
const RESULTADOS_POR_PAGINA = 10;

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

  campoBusca = new FormControl();
  mensagemErro = '';
  livrosResultado: LivrosResultado;
  paginaAtual = 0;
  private paginaAtualSubject = new BehaviorSubject<number>(0);

  constructor(private service: LivroService) { }

  livrosEncontrados$ = combineLatest([
      this.campoBusca.valueChanges.pipe(
        debounceTime(PAUSA),
        filter((valorDigitado) => valorDigitado.length >= 3),
        tap(() => {
          this.paginaAtual = 0;
          this.paginaAtualSubject.next(this.paginaAtual);
        })
      ),
      this.paginaAtualSubject
    ])
    .pipe(
      switchMap(([valorDigitado, paginaAtual]) => this.service.buscar(valorDigitado, paginaAtual * RESULTADOS_POR_PAGINA, RESULTADOS_POR_PAGINA)),
      map(resultado => this.livrosResultado = resultado),
      tap((retornoAPI) => console.log(retornoAPI)),
      map(resultado => resultado.items ?? []),
      map((items) => this.livrosResultadoParaLivros(items)),
      catchError((erro) => {
        console.log(erro)
        return throwError(() => new Error(this.mensagemErro = 'Ops, ocorreu um erro. Recarregue a aplicação!'))
      })
    );

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

  proximaPagina() {
    this.paginaAtual++;
    this.paginaAtualSubject.next(this.paginaAtual);
  }

  paginaAnterior() {
    if (this.paginaAtual > 0) {
      this.paginaAtual--;
      this.paginaAtualSubject.next(this.paginaAtual);
    }
  }
}
  • lista-livreo.component.html:
//CÓDIGO OMITIDO

<div>
    <button (click)="paginaAnterior()" [disabled]="paginaAtual === 0">Página Anterior</button>
    <button (click)="proximaPagina()">Próxima Página</button>
  </div>
  
//CÓDIGO OMITIDO

Além disso, caso queira mais informações sobre como criar paginação em um projeto Angular usando a biblioteca RxJS, você pode ler este artigo. As informações estão em inglês, mas caso queira traduzir, basta clicar com o botão direito do mouse e selecionar a opção "Traduzir para o português".

Espero ter ajudado. Caso tenha dúvidas, conte com o fórum. Abraços!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Sensacional, muuuito obrigado pela solução e por esta aula. Irei implementar após minha revisão quinta-feira.

Desde já, agradeço muito, abraços!!!