0

I am stuck in one function. I'm trying to render list of books - this list is an array of objects. But before rendering it to the HTML, I have to check if all three properties are present in the object i.e author, name and price and render only those having all three properties. So I use try...catch. Then I use map() to create new array and render it. Try...catch block detects errors, but objects without errors are not displayed. Here is my code:

function renderBooks(arr) {
 const list = document.getElementById("root");
 function makeElem(arrItem, arrIndex) {
 const {author, name, price} = arrItem;
 let li = document.createElement('li');
 if (!author) {
 throw new Error(`no author in book: #${arrIndex + 1}`);
 } else if (!name) {
 throw new Error(`no name in book: #${arrIndex + 1}`);
 } else if (!price) {
 throw new Error(`no price in book: #${arrIndex + 1}`);
 }
 return li.innerHTML = `<strong>Author:</strong> ${author}<br><strong>Name:</strong> ${name}<br><strong>Price:</strong> ${price}`;
 }
 arr.map((item, index) => {
 try {
 makeElem(item, index);
 return list.innerHTML = `<ul>${makeElem(item)}</ul>`;
 } catch (Error) {
 console.log(Error);
 }
 });
}
renderBooks(books);

UPD: I have updated the code, now only first book is rendered, but all other eligible books are not.

asked Feb 11, 2021 at 17:42

1 Answer 1

2

I have updated your implementation to do what I think you wanted to do :-

function renderBooks(arr) {
 const list = document.getElementById("root");
 function makeElem(arrItem, arrIndex) {
 const {author, name, price} = arrItem;
 let li = document.createElement('li');
 if (!author) {
 throw new Error(`no author in book: #${arrIndex + 1}`);
 } else if (!name) {
 throw new Error(`no name in book: #${arrIndex + 1}`);
 } else if (!price) {
 throw new Error(`no price in book: #${arrIndex + 1}`);
 }
 li.innerHTML = `<strong>Author:</strong> ${author}<br><strong>Name:</strong> ${name}<br><strong>Price:</strong> ${price}`;
 return li;
 }
 const listContainer = document.createElement('ul');
 // Incase you don't know this, read about it. Helps from performance point of view for large DOM updates.
 const listFragment = document.createDocumentFragment();
 arr.forEach((item, index) => {
 try {
 const listElement = makeElem(item, index);
 listFragment.append(listElement);
 } catch (Error) {
 console.log(Error);
 }
 });
 listContainer.append(listFragment);
 list.append(listContainer);
}
renderBooks(books);

The way your current code is - there would be a certain amount of issues. Firstly would be to take consideration of adding multiple list elements. Setting innerHTML the way you have done it will certainly override previously added li elements and you will only see one. Also .forEach makes more sense here than .map since you don't have to return a new array.

answered Feb 11, 2021 at 18:02

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.