I am creating some elements from an object returned via fetch request and wanted to know was there a better method to simplify this?
As it stands it works as expected but it seems ridiculously long for what seems like a simple task?
async function getJobs() {
const response = await fetch('https://app.beapplied.com/public/all-jobs');
const data = await response.json();
console.log(data.jobs);
for (const job of data.jobs) {
const jobContainer = document.getElementById("jobData");
const jobListing = document.createElement('li');
jobContainer.appendChild(jobListing);
jobListing.setAttribute('class', 'whr-item')
const jobLink = document.createElement('a');
jobListing.appendChild(jobLink);
jobLink.setAttribute('href', job.applyLink)
let jobTitle = document.createElement("h3");
jobTitle.innerHTML = job.title;
jobTitle.setAttribute('class', 'whr-title')
jobLink.appendChild(jobTitle);
const jobInfo = document.createElement('ul');
jobListing.appendChild(jobInfo);
jobInfo.setAttribute('class', 'whr-info')
let jobTeam = document.createElement("li");
jobTeam.innerHTML = job.team;
jobTeam.setAttribute('class', 'whr-dept')
jobInfo.appendChild(jobTeam);
let jobLocation = document.createElement("li");
jobLocation.innerHTML = job.location
jobLocation.setAttribute('class', 'whr-location')
jobInfo.appendChild(jobLocation);
}
}
getJobs()
<ul id="jobData" class="whr-items"></ul>
Since you're assigning to the .innerHTML
of the nested children, writing out the HTML string and interpolating would be equivalent and a lot more understandable at a glance:
const jobContainer = document.getElementById("jobData");
for (const job of data.jobs) {
jobContainer.insertAdjacentHTML(
'beforeend',
`<li class="whr-item">
<a href="${job.applyLink}">
<h3>${job.title}</h3>
</a>
<ul>
<li class="whr-dept">${job.team}</li>
<li class="whr-location">${job.location}</li>
</ul>
</li>
`
);
}
That said, interpolating external values directly HTML (or using .innerHTML
with external values) is a security risk, since it allows for arbitrary code execution. I'd recommend writing out the HTML without the inserted values, then insert them safely once the structure has been created. For example, you could use createElement
for the .whr-item
so you have a reference to it, insert its HTML without the dynamic values, then do
item.querySelector('a').href = job.applyLink;
item.querySelector('h3').href = job.title;
item.querySelector('.whr-dept').href = job.team;
item.querySelector('.whr-location').href = job.location;
This would be a safer approach.