/Book-Smart

Book Smart is a front-end API-driven search engine for finding books and viewing both historical and current bestseller data.

Primary LanguageHTML

Book•Smart

Overview:

Book•Smart allows users to search for books and view both current and historical bestseller data from The New York Times. Book•Smart was designed with functionality, responsiveness, and a smooth user experience at the forefront. This web application is for book lovers who want to find more information about specific titles, and their respective bestseller history (or lack thereof). Our final product allows the user to search for any book and returns an interactive gallery of titles with the ability to fetch more information about selected titles. Additional features include the ability to see current bestsellers from The New York Times, as well as viewing bestsellers on dates specified by the user. In the future, we would like to incorporate a backend server and database, which will allow the user to create a profile, login, and keep track of books they're interested in or have read. We would also like to implement other APIs which will allow the user to see reviews, and be recommended similar titles (i.e. Goodreads, etc.).


The Team:

Primary team role: APIs, JavaScript writer, Scrum/Agile, prototype/concepting
Contributions: JavaScript for all pages, which entailed designing and manipulating HTML & CSS as necessary. Implemented our stretch goal of allowing users to search for bestseller data on specific dates and displaying those on the specificbook page. Developed JavaScript functions to efficiently obtain information from three different APIs, which involved passing information retrieved from one API to another. Primary team role: Front-end Designer, Graphic Artist, Scrum/Agile, prototype/concepting

Contributions: HTML and CSS for all pages. Implemented JavaScript necessary for animations on the home, current bestsellers, and find bestsellers pages. Designed logos, the color scheme, and ensured consistent design throughout the website. Executed our stretch goals of having an 'About us' and 'FAQ' page.

Primary team role: Front-end markup and styling, prototype/concepting
Contributions: Main focus was HTML, CSS, and Design. Designed a more traditional desktop version that implements jQuery and Bootstrap4. Deployed responsive design while collaborating with team as well as consistent design throughout all desktop pages, navigation, and footers.

What we used:

Languages:

  • HTML5
  • CSS3
  • JavaScript ES6

APIs

Other:
  • AJAX
  • JSON
  • Photoshop

MVP (Minimum Viable Product):

  • Book search gallery which returns relevant titles
  • On-click, displays specific information about that title
  • Display current bestseller data from The New York Times
  • Responsive design

Stretch Goals Completed

  • Implementing a third API to dynamically add covers
  • Adding Aboutus and FAQ pages
  • Implementing the ability to search for bestseller data on specific dates

Stretch Goals Future

  • Creating a PostgreSQL database allowing users to create a profile, login, and keep track of books. Implement other APIs show reviews and recommended similar titles.
  • Implementing the traditonal desktop design and the ability to toggle between views.

Challenges & Solutions:

Some of the biggest challenges we faced with this project build included:

Challenge: Inconsistent formatting in APIs. Often paths would change arbitrarily, making it difficult to programmatically drill down required data.
Solution: Learned much more about our specific APIs through trial and error. Implemented try/catches for when data fetches may fail.

Challenge: JavaScript often executed asynchronusly.
Solution: Solving this issue require apporpiately using promises in conjuction with fetches.

Challenge: Making the site responsive for all device sizes.
Solution: After research, along with trial and error, we determined that CSS grid was the best/most responsive layout for our website.


Code Snippets:

Showcases how we fetched when a title was searched from the Google Books API.

//Event listener on the search button.
searchButton.addEventListener('click', e => {
  e.preventDefault();
  valuableGoogleObjects2 = [];
  let input = document.querySelector('#input').value;
  let userInput = input;
  let googleBookUrl = 'https://www.googleapis.com/books/v1/volumes?q=';
  // Takes the user input and inserts into the URL of the API call.
  fetch(googleBookUrl + `${userInput}` + googleBookKey)
    .then(response => {
      return response.json();
    })
    .then(json => {
      initialGoogleObjects.push(json);
    })
    .then(() => {
      // Takes the returned object from the API call and parses out desired information.
      drillDownGoogle();
    })
    .then(() => {
      // Creates and populates the cards saved from the desired data.
      createBookCards(valuableGoogleObjects);
    })
    .then(() => {
      // Clears local storage for repeating searches.
      initialGoogleObjects = [];
      valuableGoogleObjects = [];
    })
    .catch(() => {
      console.log('error');
    });
});

This snippet shows how we fetched The New York Times API, populated containers, and called a second API with the data returned from the first.

function callNYTimes() {
  //Fetches the current best sellers from <em>The New York Times</em> API
  fetch(
    'https://api.nytimes.com/svc/books/v3/lists.json?list-name=hardcover-fiction&api-key=' +
      nyTimesKey,
    { method: 'get' }
  )
    .then(response => {
      return response.json();
    })
    .then(json => {
      initialBestSellers.push(json);
    })
    .then(() => {
      // Parses out desired information.
      drillDownNYTimes();
    })
    .then(() => {
      //Populated containers with the desired information.
      for (let index = 0; index < 15; index++) {
        let card = document.getElementById(`${index}`);
        let image = 'http://placecorgi.com/250';
        card.innerHTML = `

        <img id="image${index}" src=${image} /><br>
        ${valuableBestSellers[index].Rank}.<br>
        ${valuableBestSellers[index].Title}<br>
        ${initialBestSellers[0].results[index].book_details[0].author}<br>
        Weeks as a Best Seller: ${initialBestSellers[0].results[index].weeks_on_list}<br>
        <p class="hidden" id="isbn${index}">${valuableBestSellers[index].ISBN10}</p>
        `;
      }
    })
    .then(() => {
      //Using the ISBN returned from the first API, queries a second API for cover images.
      pullCoversandReplaceFromOpenLibrary();
    });
}

This bit of code is very similar to the last, but shows how we adapted The New York Times call for dates specified by the user.

//The function takes the date input by the user as an argument.
function callNYTimes(dateToCheck) {
  // The date passed in is then used to fetch a specific bestsellers.
  fetch(
    `https://api.nytimes.com/svc/books/v3/lists/${dateToCheck}/hardcover-fiction.json?api-key=` +
      nyTimesKey,
    { method: 'get' }
  )
    .then(response => {
      return response.json();
    })
    .then(json => {
      initialBestSellers.push(json);
    })
    .then(() => {
      drillDownNYTimes();
    })
    .then(() => {
      for (let index = 0; index < 15; index++) {
        let card = document.getElementById(`${index}`);
        let image = 'http://placecorgi.com/250';
        card.innerHTML = `

          <img id="image${index}" src=${image} /><br>
          ${valuableBestSellers[index].Rank}.<br>
          ${valuableBestSellers[index].Title}<br>
          ${valuableBestSellers[index].Author}<br>
          Weeks as a Best Seller: ${valuableBestSellers[index].WeeksOnList}<br>
          <p class="hidden" id="isbn${index}">${valuableBestSellers[index].ISBN10}</p>
          `;
      }
    })
    .then(() => {
      pullCoversandReplaceFromOpenLibrary();
    });
}

Live Demo

https://www.youtube.com/watch?v=tzjPDPcbg8s&feature=youtu.be

Screenshots:

Highlights the landing page and search feature of Book•Smart


Modal displayed after selecting a title


Displays current bestsellers list.


Displays searched for bestsellers list.


Showcases our About section.


Showcases our FAQ section.