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.