Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

148
Views
How to preserve an order of divs generated by Javascript

I am consuming an api in which I want to show the generated data in my HTML. For that I am creating the div elements using JavaScript. When displaying the information it does it without problems, but every time I update the page, the data shows them in a different order. That is, if I have 3 divs, the div that was first will now appear last and thus the order changes each time I update the page.

This is my Javascript code:

const cargar_noticias_recientes = async () => {
    const noticias_recientes = document.querySelector('#pnl-body-content-card-reci');
    const res = await fetch(`WebService_Default.asmx/cargar_card_noticia_recientes`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: ''
    });
    const datos = await res.json();
    let nuevos = [...datos.d];
    nuevos.map(async nuevo => {
        const div = document.createElement('div');
        const peticion = await fetch(`http://localhost:51482/api/values/${nuevo[3]}`, {
            method: 'GET'
        });
        const imagen = await peticion.blob();
        const url = URL.createObjectURL(imagen);
        div.innerHTML = `
            <div class="body-card body-card-reci ${nuevo[0]}">
                <div class="card-title">
                    <span>Nuevo</span>
                </div>
                <div class="img-card">
                    <div class="img" style="background-image: url(${url});"></div>
                </div>
                <div class="content-card">
                    <p>
                        <i class="fas fa-tags"></i> ${nuevo[1]}
                    </p>
                </div>
            </div>
        `
        noticias_recientes.appendChild(div);
    });
}
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Your problem is related to the use of asynchronous.

    nuevos.map(async nuevo => {
        const div = document.createElement('div');
        const peticion = await fetch(`http://localhost:51482/api/values/${nuevo[3]}`, {
            method: 'GET'
        });
        const imagen = await peticion.blob();
        const url = URL.createObjectURL(imagen);
        div.innerHTML = `
            <div class="body-card body-card-reci ${nuevo[0]}">
                <div class="card-title">
                    <span>Nuevo</span>
                </div>
                <div class="img-card">
                    <div class="img" style="background-image: url(${url});"></div>
                </div>
                <div class="content-card">
                    <p>
                        <i class="fas fa-tags"></i> ${nuevo[1]}
                    </p>
                </div>
            </div>
        `
        noticias_recientes.appendChild(div);
    });

In this function you do a fetch. This is an HTTP request that has some more or less random execution time. The first fetch that finishes will be the first div created, the second fetch that finishes will be the second div created, and so on.

If you want to constantly keep the order of your divs creation, you have to get it out of your map callback because each fetch doesn't wait for the previous one to finish. Like this :

for (nuevo of nuevos) {
    const div = document.createElement('div');
    const peticion = await fetch(`http://localhost:51482/api/values/${nuevo[3]}`, {
        method: 'GET'
    });
    const imagen = await peticion.blob();
    const url = URL.createObjectURL(imagen);
    div.innerHTML = `
            <div class="body-card body-card-reci ${nuevo[0]}">
                <div class="card-title">
                    <span>Nuevo</span>
                </div>
                <div class="img-card">
                    <div class="img" style="background-image: url(${url});"></div>
                </div>
                <div class="content-card">
                    <p>
                        <i class="fas fa-tags"></i> ${nuevo[1]}
                    </p>
                </div>
            </div>
        `
    noticias_recientes.appendChild(div);
}

This way, each fetch will wait patiently for the previous one to finish, and your divs will always be created in the same order.

Beware that it is clearly not optimized to do this. Because your requests are no longer done in parallel, but one after the other. So the execution time of this function will be (avgTimeOfFetch) * nbRequestToDo seconds

If you want something more optimized, you should probably keep running your requests in parallel as you did in your initial version, then sort data the way you want, and then at that point you can create your divs and insert them in the DOM.

about 4 years ago · Juan Pablo Isaza Report

0

The different order may occur because some of the await-ed promises within the multiple map callbacks may resolve sooner than others, giving a different order of execution.

You can get back the results in their original order by using Promise.all -- still allowing the non-JS asynchronous tasks to run independently of each other:

    const promises = nuevos.map(async nuevo => {
        const div = document.createElement('div');
        const peticion = await fetch(`http://localhost:51482/api/values/${nuevo[3]}`, {
            method: 'GET'
        });
        const imagen = await peticion.blob();
        const url = URL.createObjectURL(imagen);
        div.innerHTML = `
            <div class="body-card body-card-reci ${nuevo[0]}">
                <div class="card-title">
                    <span>Nuevo</span>
                </div>
                <div class="img-card">
                    <div class="img" style="background-image: url(${url});"></div>
                </div>
                <div class="content-card">
                    <p>
                        <i class="fas fa-tags"></i> ${nuevo[1]}
                    </p>
                </div>
            </div>
        `;
        // Don't append to the DOM yet, but *return*
        return div;
    });
    // Collect the DIVs in the order of the originally fetched data:
    const divs = await Promise.all(promises);
    // ...And populate the DOM
    for (const div of divs) noticias_recientes.appendChild(div);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!