Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

147
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda