Reputation: 1
I am trying to use Google Book API for my project app which it's intention is; the user can search the title and author of a book that they have read and in response you will get the title and author and the cover image extracted from google book API.
I am able to get all the total items through the search title and author from the API but I can not specify to respond only the first item from the search and most importantly the smallThumbnail
which will be the cover image for the search book.
I am using in the backend postgres as my db and ejs on my frontend.
I know the smallThumbnail
is under volumeInfo
which is under imageLinks
, I just can not make it show in my front ejs
// Import necessary modules
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
const { Client } = require('pg');
const path = require('path');
// Create Express app
const app = express();
const port = 3000;
// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// PostgreSQL Client
const client = new Client({
user: process.env.DB_USER || 'postgres',
host: process.env.DB_HOST || 'localhost',
database: process.env.DB_NAME || 'book_notes_db',
password: process.env.DB_PASSWORD || 'na',
port: process.env.DB_PORT || 5432,
});
// Connect to PostgreSQL database
client.connect()
.then(() => console.log('Connected to PostgreSQL database'))
.catch(error => console.error('Error connecting to PostgreSQL database:', error));
// EJS Setup
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Serve static files from the public directory
app.use(express.static(path.join(__dirname, 'public')));
// Route for the root URL
app.get('/', async (req, res) => {
try {
const dbData = await fetchDataFromDatabase();
const booksData = await fetchDataFromAPI(dbData);
res.render('index', { dbData, booksData });
} catch (error) {
handleError(res, error);
}
});
// POST a new book with title and author only
app.post('/books', async (req, res) => {
console.log('Received data:', req.body);
const { title, author } = req.body;
try {
// Update database with ISBN
await client.query('INSERT INTO books (title, author) VALUES ($1, $2)', [title, author]);
let image_link = null; // Initialize cover image URL
// Update database with cover image URL if it's available
if (image_link) {
await client.query('UPDATE books SET image_link = $1 WHERE isbn = $2', [image_link, isbn]);
}
// Fetch data from the database
const dbData = await fetchDataFromDatabase();
// Render the page with updated data and the relevant book data
const bookData = await fetchBookData(title, author,image_link); // Fetch additional book data
res.status(201).render('index', { dbData, bookData }); // Pass both dbData and bookData to the template
} catch (error) {
handleError(res, error);
}
});
// DELETE a book by ID
app.delete('/books/:book_id', async (req, res) => {
const bookId = req.params.book_id;
try {
await client.query('DELETE FROM books WHERE book_id = $1', [bookId]);
const dbData = await fetchDataFromDatabase();
const booksData = await fetchDataFromAPI(dbData);
res.status(200).json({ success: true, message: 'Book deleted successfully', data: dbData });
} catch (error) {
handleError(res, error);
}
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
// Function to fetch data from the database
async function fetchDataFromDatabase() {
const { rows: dbData } = await client.query('SELECT * FROM books');
return dbData;
}
// Function to fetch additional data from the API
async function fetchDataFromAPI(dbData) {
// Implement logic to fetch additional data from the API if needed
// For now, return the original data
return dbData;
}
async function fetchBookData(title, author) {
const apiUrl = `https://www.googleapis.com/books/v1/volumes?q=intitle:${encodeURIComponent(title)}+inauthor:${encodeURIComponent(author)}&key=na`;
try {
const response = await axios.get(apiUrl);
console.log('Google Books API response_bookData:', response.data.items);
const items = response.data.items;
if (!items || items.length === 0) {
console.error('No books found for the given search criteria');
return null;
}
// Extract data from the first item
const firstItem = items[0];
const volumeInfo = firstItem.volumeInfo;
const bookData = {
title: volumeInfo.title,
author:volumeInfo.authors ? firstItem.volumeInfo.authors.join(', ') : 'Unknown Author',
smallThumbnail:volumeInfo.imageLinks?.smallThumbnail || ''
};
return bookData;
} catch (error) {
console.error('Error fetching book data:', error);
throw error; // Rethrow the error to be caught by the caller
}
}
// Function to handle errors
function handleError(res, error) {
console.error('Error:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
Upvotes: 0
Views: 94