Bare with me, still a js noob.
I'm doing a Fetch GET request to my database. JSON response is working to the console, I can see an array of 5 unique items. No console errors.
But rendering to the page I only get two items to display. Item 0 repeats 4 times and item 4 displays once. Odd. Something wrong with the way I'm using the "for...of"loop I guess, but I've pulled my hair out trying stuff and dunno what I'm doing.
Appreciate anyones help here. Jobslist Dashboard Screenshot attached [1]: https://i.stack.imgur.com/Xb9Ra.jpg [![dashboard][1]][1]
let url = new URL('//HIDDEN_URL_ENDPOINT');
async function getJobs() {
let data;
try {
const response = await fetch(url);
data = await response.json();
} catch (error) {
console.log('error', error);
}
const jobContainer = document.getElementById("job_list");
const jobRecords = data;
for (const jobRecord of jobRecords) {
const style = document.getElementById('sample_job')
const job = style.cloneNode(true)
job.setAttribute('id', 'nodeJobs');
document.querySelector("#job_title").innerHTML = jobRecord.job_title;
document.querySelector("#job_type").innerHTML = jobRecord.job_type;
document.querySelector("#job_level").innerHTML = jobRecord.job_level;
document.querySelector("#job_salary").innerHTML = jobRecord.job_salary;
document.querySelector("#job_status").innerHTML = jobRecord.job_status;
document.querySelector("#formated_date").innerHTML = jobRecord.formated_date;
document.querySelector("#page_views").innerHTML = jobRecord.page_views;
document.querySelector("#apply_clicks").innerHTML = jobRecord.apply_email_clicks;
jobContainer.appendChild(job);
}
}
getJobs();
CodePudding user response:
The problem is that:
querySelector
will return the first match, so it will always find the same element in each iteration of the loop, and -- related --- you generate HTML that has
id
attributes that are not unique (which is invalid in HTML)
So:
- Don't give the cloned elements an
id
attribute at all. You shouldn't need that. The original sample element could have oneid
, but remove it in the clone. - Don't use
id
attributes in this template's inner structure at all, but useclass
instead - Make
querySelector
calls that start from the element that was just added, notdocument
Something like this (after you have adapted the HTML of sample_job
):
for (const jobRecord of jobRecords) {
const style = document.getElementById('sample_job')
const job = style.cloneNode(true)
job.removeAttribute('id');
job.querySelector(".job_title").innerHTML = jobRecord.job_title;
job.querySelector(".job_type").innerHTML = jobRecord.job_type;
job.querySelector(".job_level").innerHTML = jobRecord.job_level;
job.querySelector(".job_salary").innerHTML = jobRecord.job_salary;
job.querySelector(".job_status").innerHTML = jobRecord.job_status;
job.querySelector(".formated_date").innerHTML = jobRecord.formated_date;
job.querySelector(".page_views").innerHTML = jobRecord.page_views;
job.querySelector(".apply_clicks").innerHTML = jobRecord.apply_email_clicks;
jobContainer.appendChild(job);
}
The HTML wasn't provided, but the idea is something like this:
<div id="sample_job">
<div ></div>
<div ></div>
<!-- ...etc... -->
</div>
CodePudding user response:
You just need to replace document
by your job
element, and preferably replace all ids by classnames for example because the id should be unique (and of course replace the #
in the selector by .
if you did so):
job.querySelector("#job_title").innerHTML = jobRecord.job_title;
job.querySelector("#job_type").innerHTML = jobRecord.job_type;
job.querySelector("#job_level").innerHTML = jobRecord.job_level;
job.querySelector("#job_salary").innerHTML = jobRecord.job_salary;
job.querySelector("#job_status").innerHTML = jobRecord.job_status;
job.querySelector("#formated_date").innerHTML = jobRecord.formated_date;
job.querySelector("#page_views").innerHTML = jobRecord.page_views;
job.querySelector("#apply_clicks").innerHTML = jobRecord.apply_email_clicks;