It doesnt always show all the books on my homepage

45 views Asked by At

I am working on a Angular project. My aim is to make a book finder application using Google Books API and the problem is that sometimes when i refresh the page or I go to a different component and go back to my homepage it sometimes doesnt show any books even though the status code is 200. I checked the console and its supposed to send an array named items. When the error occurs it doesnt send that array.

all-books.component.ts :

import { Component, OnInit } from '@angular/core';
import { BookService } from '../book.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-all-books',
  templateUrl: './all-books.component.html',
  styleUrls: ['./all-books.component.css']
})
export class AllBooksComponent implements OnInit {
  books: any[] = [];
  loading: boolean = true;
  error: string | null = null;

  searchQuery: string = '';
  searchBy: string = 'title';

  constructor(private bookService: BookService, private router: Router) { }

  ngOnInit(): void {
    this.fetchBooks();
  }

  fetchBooks(): void {
    this.loading = true; 
    this.bookService.getRandomBooks()
      .subscribe(
        (data: any) => {
          console.log("API Response:", data); 
          if (data && data.items && data.items.length > 0) {
            this.books = data.items.slice(0, 9);
            this.error = null; 
          } else {
            this.books = []; // Reset books array
            this.error = 'No books found.';
          }
          this.loading = false;
        },
        (error) => {
          console.error('Error fetching random books:', error);
          this.error = 'Failed to fetch books. Please try again later.';
          this.books = []; 
          this.loading = false;
        }
      );
  }

  search(): void {
    this.loading = true;
    this.bookService.searchBooks(this.searchQuery, this.searchBy)
      .subscribe(
        (data: any) => {
          if (data && data.items && data.items.length > 0) {
            this.books = data.items;
            this.error = '';
          } else {
            this.books = [];
            this.error = 'No books found.';
          }
          this.loading = false;
        },
        (error) => {
          console.error('Error fetching search results:', error);
          this.error = 'Failed to fetch search results. Please try again later.';
          this.books = []; // Reset books array
          this.loading = false;
        }
      );
  }
}

all-books.component.html :

<div class="container">
    <div class="row mt-5 justify-content-center">
      <div class="col-md-6">
        <div class="input-group">
          <input type="text" [(ngModel)]="searchQuery" class="form-control" placeholder="Search for books..." />
          <select [(ngModel)]="searchBy" class="form-select">
            <option value="title">Title</option>
            <option value="author">Author</option>
            <option value="isbn">ISBN</option>
          </select>
          <button (click)="search()" class="btn btn-primary">Search</button>
        </div>
      </div>
    </div>
  
    <p class="text-center font fw-bold mt-5">Here are a selection of our books</p>
    <div class="container mt-3">
      <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 justify-content-center">
        <div class="col" *ngFor="let book of books">
          <div class="card h-100">
            <img [src]="book.volumeInfo?.imageLinks?.thumbnail" alt="No Book Cover Available" class="card-img-top" style="height: 350px; object-fit: cover;">
            <div class="card-body">
              <h5 class="card-title">{{ book.volumeInfo?.title }}</h5>
              <ul class="list-group list-group-flush text-center">
                <li class="list-group-item">Author: {{ book.volumeInfo?.authors?.join(', ') || 'Unknown' }}</li>
                <li class="list-group-item">Release date: {{ book.volumeInfo?.publishedDate || 'Unknown' }}</li>
                <li class="list-group-item">Publisher: {{ book.volumeInfo?.publisher || 'Unknown' }}</li>
              </ul>
            </div>
            <div class="card-footer d-flex justify-content-center">
                <a [routerLink]="['/book-details']" [queryParams]="{ bookId: book.id }" class="btn btn-primary fixed-button-size">Details</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

book.service.ts :

import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";

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

  private apiUrl: string = 'https://www.googleapis.com/books/v1/volumes';
  private apiKey: string = 'myApiKey';

  constructor(private http: HttpClient) { }

  searchBooks(query: string, searchBy: string): Observable<any> {
    let url: string;
    if (searchBy === 'title') {
      url = `${this.apiUrl}?q=intitle:${query}&key=${this.apiKey}`;
    } else if (searchBy === 'author') {
      url = `${this.apiUrl}?q=inauthor:${query}&key=${this.apiKey}`;
    } else if (searchBy === 'isbn') {
      url = `${this.apiUrl}?q=isbn:${query}&key=${this.apiKey}`;
    } else {
      url = `${this.apiUrl}?q=${query}&key=${this.apiKey}`;
    }
    return this.http.get(url);
  }

  getRandomBooks(): Observable<any> {
    const randomPage = Math.floor(Math.random() * 100);
    const query = 'fiction'; 
    const url = `${this.apiUrl}?q=${query}&startIndex=${randomPage * 10}&maxResults=10&key=${this.apiKey}`;
    return this.http.get(url);
  }

  getBookDetails(bookId: string): Observable<any> {
    const url = `${this.apiUrl}/${bookId}?key=${this.apiKey}`;
    return this.http.get(url);
  }
}

I tried debugging and also tried fixing it with chatGPT but it didn't work.

0

There are 0 answers