I am trying to fetch some info from an api where it gives name, authorname, publisher and firstpublish year of book. but sometimes the firstpublish year is missing. I want to show this informations in a page. I am writing these piece of code ---
const searchResultShow = data => {
parentDiv = document.getElementById('result-details');
parentDiv.innerText = "";
data.docs.forEach(key=>{
bookName = key.title;
authorname = key.author_name[0];
publisher = key.publisher[0];
newElem = document.createElement('div')
newElem.classList.add('col')
if ('first_publish_year' in key){
firstPublish = key.first_publish_year;
newElem.innerHTML = `
<h4>Name: ${bookName}</h3>
<h4>Author Name: ${authorname}</h4>
<h4>Publisher: ${publisher}</h4>
<h4>First Publish Year: ${firstPublish}</h4>
`
}
else {
newElem.innerHTML = `
<h4>Name: ${bookName}</h3>
<h4>Author Name: ${authorname}</h4>
<h4>Publisher: ${publisher}</h4>
`
}
parentDiv.appendChild(newElem);
})
As you can see this is not efficient, I am writing newElem.innerHTML twice. And if some other parameters are missing, I have to repeat this again and again. What could be an easy solution to get rid of this repeating situation?
The easiest way is probably to separate out the lines, then combine them:
const firstPublishHTML = ('first_publish_year' in key) ? `<h4>First Publish Year: ${key.first_publish_year}</h4>` : ''
...
newElem.innerHTML = `<h4>Name: ${bookName}</h4>
...
${firstPublishHTML}...`
Basically, if the element is present, your variable is a valid HTML line, if it's not, it's an empty string
You can try adding/concatenating strings like this:
Since this looks like it won't be changed part of code:
`newElem.innerHTML` =
<h4>Name: ${bookName}</h3>
<h4>Author Name: ${authorname}</h4>
<h4>Publisher: ${publisher}</h4>
You can do like following:
newElem.innerHTML = `
<h4>Name: ${bookName}</h3>
<h4>Author Name: ${authorname}</h4>
<h4>Publisher: ${publisher}</h4>
`
if ('first_publish_year' in key){
firstPublish = key.first_publish_year;
newElem.innerHTML += `<h4>First Publish Year: ${firstPublish}</h4>`
}
Typically for this sort of thing I would try and use a null check that resides in-line instead of a wrapping if statement. That'll keep it DRY and let you add a function to resolve the data later if you ever get that option. In this way you can keep tacking conditionals onto your template and slowly build it out.
const searchResultShow = data => {
parentDiv = document.getElementById('result-details');
parentDiv.innerText = "";
data.docs.forEach(key=>{
bookName = key.title;
authorname = key.author_name[0];
publisher = key.publisher[0];
newElem = document.createElement('div')
newElem.classList.add('col')
newElem.innerHTML = `
<h4>Name: ${bookName}</h3>
<h4>Author Name: ${authorname}</h4>
<h4>Publisher: ${publisher}</h4>
`
newElem.innerHTML += (('first_publish_year' in key) ? `<h4>First Publish Year: ${key.first_publish_year}</h4>` : ``);
}
parentDiv.appendChild(newElem);
})
Alternatively, since this is going to be parsed, you can have a string that you build onto, and then make a single call to innerHTML with that string:
const searchResultShow = data => {
parentDiv = document.getElementById('result-details');
parentDiv.innerText = "";
data.docs.forEach(key=>{
let innerHTMLString = "";
bookName = key.title;
authorname = key.author_name[0];
publisher = key.publisher[0];
newElem = document.createElement('div')
newElem.classList.add('col')
innerHTMLString += `
<h4>Name: ${bookName}</h3>
<h4>Author Name: ${authorname}</h4>
<h4>Publisher: ${publisher}</h4>
`
innerHTMLString += (('first_publish_year' in key) ? `<h4>First Publish Year: ${key.first_publish_year}</h4>` : ``);
newElem.innerHTML(innerHTMLString);
}
parentDiv.appendChild(newElem);
})
Making it marginally more efficient not having to call innerHTML twice. This is a better technique as your code gets more evolved and you may be performing numerous calls to the innerHTML function.