extract individual components from the google books api

It has been quite a while since I last dabbled in JavaScript, so I decided to embark on a project creating a "bookcase" to organize the books I have read and those I still want to read. One challenge I encountered was figuring out how to separate the elements for custom styling as all results from the API were being placed within a single div.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="script.js"></script>
    <link rel="stylesheet" href="./css/bookcase.css">
    <title>Project</title>
</head>
<body>

    <div id="content">
    </div>

    <script src="https://www.googleapis.com/books/v1/volumes?q=clean+code&callback=handleResponse></script>
</body>
</html>

JavaScript

function handleResponse(response) {
    for (var i = 0; i < response.items.length; i++) {
      var item = response.items[i];
      var book = document.getElementById('content')
      book.innerHTML += "<br>" + '<img src=' + response.items[i].volumeInfo.imageLinks.thumbnail + '>';
      book.innerHTML += "<br>" + item.volumeInfo.title;
      book.innerHTML += "<br>" + item.volumeInfo.authors;

Answer №1

Valuable advice - opt for document.appendChild(child) over the innerHTML method for a cleaner solution.


Furthermore, explore the latest JavaScript methods like map, reduce, and filter to efficiently handle large JSON objects.

I have included an example demonstrating how you can extract essential data from the original object, create a smaller array, and then populate HTML elements with items from that array.

function demo (obj) {
  // extracting all items from the object

  const book = Object.keys(obj).map(item => obj['items']).reduce(
    (acc,rec, id, array) => {

      // obtaining Cover, Title, Author from each item
      let singleBookCover = rec[id].volumeInfo.imageLinks.thumbnail;
      let singleBookTitle = rec[id].volumeInfo.title;
      let singleBookAuthor = rec[id].volumeInfo.authors[0];

      // creating a new array with only Cover, Title, Author
      return [...acc, {singleBookCover, singleBookTitle, singleBookAuthor}]
    },
    []
  ).forEach( item => {

    // For each item in our array, we generate an h1 element
    let title = document.createElement('h1');
    title.textContent = `${item.singleBookTitle} by ${item.singleBookAuthor}`;

    // image
    let img = document.createElement('img');
    img.src = item.singleBookCover;
    img.alt = `${item.singleBookTitle} by ${item.singleBookAuthor}`;

    // creating a div wrapper
    let container = document.createElement('div');

    // appending child elements to the wrapper
    container.appendChild(title).appendChild(img);

    // adding the wrapper to the body
    document.body.appendChild(container);
   })
  return book
}

I trust that my explanation will be beneficial to you)

Answer №2

function handleData(response) {
  const container = document.getElementById("container")
  response.items.forEach((book, index) => {
    let cover = book.volumeInfo.imageLinks && book.volumeInfo.imageLinks.smallThumbnail;
    let title = book.volumeInfo.title;
    let author = book.volumeInfo.authors[0];
    let newBook = document.createElement("div");
    newBook.className = "book"
    newBook.innerHTML = `
    <div><h1>${title}<h1>
    <p>${author}</p>
    <img src="${cover}"></img>
    </div>
    `
    content.appendChild(newBook)
  });
}
 <div id="content" class="books">
        </div>

        <script src="https://www.googleapis.com/books/v1/volumes?q=clean+code&callback=handleData"></script>
        

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble getting my image and text to align properly in two columns

<img id="story_image" src="images/builder_story_side.png" alt="photo"/> <div id="story_right"> <h2 class="story_header">fdgdfgdfgdfgdfgfdgdfgfdgdfgdfgdfgdfgdfgdfgdfgdfgdfgfdgdfgdfgdfgdfgdfgdfgdfgdfgdfgdfgdfgdfgdfgdfgdfg</h2> <p ...

There seems to be a lack of definition for Angular within the angular

Currently, I am in the process of developing an Angular application. The modules I have created contain services and controllers that are all working as intended. Recently, I added angular-animate to my list of scripts, which are loaded from a cshtml file ...

The hideCol method does not work on jqGrid

Encountering a problem with the hidecol method in jqGrid. Despite calling the method, nothing seems to happen. Using version 4.5 of jqGrid. The table is created as follows: // Table creation using jqGrid $('#shipTable').jqGrid({ data: tabl ...

Angular Js powered admin control panel

Explore the SB Admin Angular by Start Angular My current project involves setting up an admin dashboard on a Windows system. However, I have encountered some issues during the installation process using npm install An error message can be found here ...

Every time an npm installation is attempted, the following error occurs: "npm ERR! Cannot read property 'resolve' of undefined."

Welcome Everyone! Currently, I am facing an issue on my dual boot system where Node and NPM were functioning smoothly on Windows 7. However, now that Windows 7 is not booting up, presumably due to hardware problems, I have resorted to using Windows 10. E ...

What is the best way to ensure that a specific number of XHR callbacks have successfully completed before proceeding with further actions?

I have four requests that each have their own callback and can fire in any order. However, I need all the callbacks to finish successfully before executing mergeData. The issue with my current approach is that the initial parameter values do not refresh ...

Tips for choosing a specific set of list items using HTML

In my application, I have a list that is divided into sections like "currently viewing as," "recently viewed," and "staff." All elements in the list share the same classes, making it difficult to identify a specific list element in a particular section, su ...

"Dealing with an unspecified number of fields in an ExtJS data model

I have a data model that is designed to accommodate various incoming data by keeping it generic and allowing for the addition of multiple meta data tags to my project. How can I effectively map these data fields to the Model or access them in the array w ...

Utilize both a model and a boolean variable within expressionProperties in Formly configuration

I'm having trouble setting formly form fields to disabled based on model properties and a boolean variable. The code snippet I've tried doesn't seem to be working as expected. expressionProperties: { 'templateOptions.disabled' ...

Tips for successfully incorporating PHP dynamic parameters separated by commas into a JavaScript onclick function

How can I pass PHP dynamic parameters separated by commas to a JavaScript onclick function? Can someone assist me with the correct solution? The code below is not working as expected. echo "<td><a href='#' onclick='editUser(". $row ...

Images that adjust to different screen sizes within a grid layout

I have four images that need to be aligned in the following layout: ____________ |1 |4 | |_____| | |2 |3| | |__|__|______| They must be flush against each other, occupy 100% of the viewport's width, and most importantly, be respon ...

Ways to enlarge a YouTube thumbnail upon loading using JavaScript

I recently found a solution to my question on how to prevent YouTube videos from repeating even when different embedded codes are used. I have a specific need to resize the thumbnail image of my YouTube video to width:146px and height:124px when the page l ...

Encountering issues with loading Angular formControl

I've been going through an Angular tutorial on forms, which you can check out here. In my 'datasources.component.html' file, I have the following code: <form [formGroup]="queryForm"> <label>Query: <input type="text" formCont ...

Design an arrangement using div elements and CSS styling

Creating a layout for a website can be challenging. I am using three div tags - container, left, and right. My goal is to have the left side fixed-width for navigation, while the right side displays dynamic content loaded from a database. However, I'm ...

Glitches and sudden jumps occur when using the useMediaQuery function in Material UI

Implementing Material UI's useMediaQuery() hook, I have embedded the theme provider and initialized a variable in this way: const theme = useTheme(); const isSmall = useMediaQuery(theme.breakpoints.down('sm') ); I am utilizing the isSmall v ...

Custom Wikipedia HTML template for a unique and immersive user experience

I am looking to develop a wiki website similar to Wikipedia using .Net, but I am having difficulty finding an HTML template that resembles it. Can anyone provide information on the template or framework used by Wikipedia and where I can get it? ...

Where is the location of the directory on the hard drive that was created using the getDirectory() method in HTML5?

I have been working on creating, deleting, and reading directories but I am unsure of where they are located on the hard drive. fs.root.getDirectory('something', {create: true}, function(dirEntry) { alert('Congratulations! You have succes ...

Apply the active class to only one element at a time

Presented here is a table showcasing available dates and times. Users can select a specific time by clicking on the "Choose" link. Currently, when a user selects a time, the class "active" is applied. However, the desired behavior is to remove the previous ...

Unlimited scrolling feature in Ionic using JSON endpoint

Trying to create an Ionic list using data from a JSON URL. JSON Code: [{"id":"1","firstName":"John", "lastName":"Doe"}, {"id":"2","firstName":"Anna", "lastName":"Smith"}, {"id":"3","firstName":"Peter", "lastName":"Jones"},{......................}] app.j ...

Press on a circle to adjust its size to fit the section or division

Is it possible to make a circle expand and fill the section/div when clicked? I want the circle to fill the screen upon clicking, and then have some text appear in its place. Before posting this, I searched on the web and came across this jsfiddle link. ...