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.
1 Answer 1
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.
Comments
Explore related questions
See similar questions with these tags.