Hello! I need some help.
I’ve tested my code in browser and in Codecademy ide and it gives right output. But I’m not passing the test:
The filterBooks()
function takes in a search string and a list of books as parameters and returns all of the books that contain an exact match of the search input as an array of objects. Objects in this array should be formatted as books
with title
, author
, and tags
properties, similar to the original books
array. It should use the flattenObjectValuesIntoArray()
function to search all fields within a book object easily.
Error: Given the filter YA
, your filterBooks
function returned an array with 0
elements. We expected it to return 1
.
Can you explain why it’s giving an error?
script.js
// Click handler for search button
const captureSearchValue = () => {
return document.getElementById("search-bar").value.toLowerCase();
};
// Filter books based on search input
const filterBooks = (searchValue, bookList) => {
let booksArr = flattenObjectValuesIntoArray(bookList).filter((bookArr) =>
bookArr.map((item) => item.toLowerCase()).includes(searchValue)
);
return booksArr.map((arr) => {
return {
title: arr[0],
author: arr[1],
tags: [arr.slice(2, arr.length)],
};
});
};
// Empty the book list container, iterate over list of filtered books, return list of books formatted as HTML using the function in `helper.js`
const structureBooksAsHtml = (filteredBooks) => {
return filteredBooks.map((book) => structureBookAsHtml(book));
};
// Handler triggered when a user clickers the "Search" button. Chains previously defined functions together to filter books based on the search value, formats the books as HTML and renders them to the DOM
const searchBtnClickHandler = () => {
let search = captureSearchValue();
let filteredBooks = filterBooks(search, books);
let formattedBooks = structureBooksAsHtml(filteredBooks);
renderBooksToDom(formattedBooks);
};
// Grab search button from the DOM
const searchBtn = document.getElementById("search-btn");
// Attach an event listener to the search button
searchBtn.addEventListener("click", () => {
searchBtnClickHandler();
});
helper.js
// Flatten object keys into an array so that we search the entire object by the input value
const flattenObjectValuesIntoArray = (arrOfObjs) => {
let flattenedObj;
const flattenedObjsArr = [];
for (let obj = 0; obj < arrOfObjs.length; obj++) {
const objValues = Object.values(arrOfObjs[obj]);
flattenedObj = [...objValues.flat()]
flattenedObjsArr.push(flattenedObj)
}
return flattenedObjsArr;
};
// Structure filtered books as HTML and return
const structureBookAsHtml = (book) => {
const bookDiv = document.createElement("div");
bookDiv.setAttribute('class', 'bookDiv');
const bookTitle = document.createElement("h2");
bookTitle.innerHTML = book.title;
bookTitle.setAttribute('class', 'bookTitle');
const bookAuthor = document.createElement("h3");
bookAuthor.innerHTML = book.author;
const bookTags = document.createElement("p");
bookTags.innerHTML = book.tags.join(", ");
bookDiv.append(bookTitle, bookAuthor, bookTags);
return bookDiv;
};
const renderBooksToDom = (elements) => {
const bookListContainer = document.querySelector("#bookList");
bookListContainer.innerHTML = "";
bookListContainer.append(...elements);
};
bookList.js
const books = [
{
title: "The City We Became",
author: "N. K. Jemisin",
tags: [
"fantasy",
"fiction",
"afrofutursim",
"science fiction",
"sci-fi",
],
},
{
title: "The Catcher in the Rye",
author: "J. D. Salinger",
tags: [
"fiction",
"young adult",
"YA",
"realism",
"coming of age",
"classic",
],
},
{
title: "The Hundred Thousand Kingdoms",
author: "N. K. Jemisin",
tags: ["fantasy", "fiction", "adventure", "series"],
},
{
title: "Sapiens: A Brief History of Humankind",
author: "Yuval Noah Harari",
tags: ["nonfiction", "history", "anthropology", "science", "sociology"],
},
{
title: "Behave: The Biology of Humans at Our Best and Worst",
author: "Robert M. Sapolsky",
tags: ["nonfiction", "anthropology", "science", "sociology", "biology"],
},
{
title: "The Parable of the Talents",
author: "Octavia Butler",
tags: ["fiction", "dystopian", "science fiction"],
},
{
title: "1984",
author: "George Orwell",
tags: ["fiction", "dystopian", "science fiction", "classics", "adult"],
},
{
title: "Remarkably Bright Creatures",
author: "Shelby Van Pelt",
tags: ["fiction", "mystery", "magical realism"],
},
{
title: "Crying in H Mart",
author: "Michelle Zauner",
tags: ["memoir", "nonfiction", "autobiography"],
},
{
title: "Wild: From Lost to Found on the Pacific Crest Trail",
author: "Cheryl Strayed",
tags: ["nonfiction", "memoir", "adventure", "travel"],
},
];
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
<script src="bookList.js"></script>
<script src="bookList.test.js"></script>
<script src="helper.js"></script>
<script src="script.js" defer></script>
</head>
<body>
<h1>Book Finder</h1>
<input id="search-bar" type="text" placeholder="Search for books by tags">
<button class="btn" id="search-btn">Search</button>
<div id="bookList">
<!-- List of books will be rendered here -->
</div>
</body>
</html>