What is the best way to add data from an array to a DOM element in the same order it was retrieved from Firebase?

Utilizing Google Firebase Firestore for data storage and the Open Movie Database (OMD) in combination with Axios to retrieve movie information.

I am currently developing a website that allows users to add movies to collections. On the collections page, all the movies added to any collection are displayed. These collections are stored within the user's Firestore document.

Below is an example of what a particular user's entire movie collections object looks like:

movies_collections = {
    "New": {
        "description": "",
        "movies": [
            "tt0092007_2021-08-19T21:00:45.072Z",
            "tt0042192_2021-08-19T21:01:06.280Z",
            "tt0160862_2021-08-19T21:01:09.345Z",
            "tt0164184_2021-08-19T21:01:12.662Z",
            "tt5294550_2021-08-19T21:01:17.820Z"
        ],
        "dateCreated": {
            "seconds": 1629406839,
            "nanoseconds": 22000000
        },
        "createdBy": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="12747d7d52757f737b7e3c717d7f">[email protected]</a>"
    },

    "Summer Watchlist": {
        "description": "to watch this summer",
        "movies": [
            "tt6964748_2021-08-20T02:37:21.933Z",
            "tt0043274_2021-08-20T02:37:29.024Z"
        ],
        "dateCreated": {
            "seconds": 1629427029,
            "nanoseconds": 718000000
        },
        "createdBy": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="15737a7a557278747c793b767a78">[email protected]</a>"
    }
}

Here is the code responsible for fetching these movies and dynamically adding them to the DOM:

const userDocRef = firebase.firestore().collection("users").doc(firebase.auth().currentUser.uid);

// Retrieve movie collections
userDocRef.get().then((doc) => {

        // Reference to movies_collections
        const movies_collections = doc.data().movies_collections;

        // Iterate over each key in movies_collections
        Object.keys(movies_collections).forEach(movies_collection_object => {

            // Get the movies array under movies_collections -> {collection_name}
            const movies_collections_movies_array = movies_collections[movies_collection_object].movies;

            // Iterate over each imdbID inside movies_collections -> {collection_name} -> movies array
            movies_collections_movies_array.forEach(movie => {

                // Extract imdbID from the movie string
                let movie_imdbID = movie.split("_")[0];

                // Retrieve movie details using OMDB API
                axios.get("https://www.omdbapi.com/?i=" + movie_imdbID + "&apikey=56bdb7b4").then((res) => {
                    // Append movie poster, title, and year to the DOM
                    document.getElementById("movies-collections-container").innerHTML +=
                        `
                    <div class="movie-container">
                        <div class="movie-image">
                            <img src=${res.data.Poster} alt="${res.data.Title} Poster">
                        </div>

                        <div class="movie-content">
                            <div class="add-content-container">
                                <div>
                                    <h2 class="movie-name">${res.data.Title}</h2>
                                    <p class="movie-release-date">Released: ${res.data.Year}</p>
                                </div>
                            </div>
                        </div>
                    </div>
                    `
                })
            })
        })
    })

The issue arises when appending movies to the DOM as they seem to appear randomly despite being retrieved in order. If I refresh the collections page, the order changes each time.

How can I ensure that my code appends each movie to the DOM based on their order in the "movies" array? The timestamp of each movie insertion into the array has also been included. *

Answer №1

The issue lies in the fact that your

axios.get("https://www.omdbapi.com/
requests are all occurring simultaneously, without any guarantee of completion order.

You have two options: carry out the requests sequentially (one after another), or add the element to the HTML prior to making the get call and then modify the element upon receiving a response.

You could implement something along these lines:

function addMovieElementToContainerForID(movie_imdbID) {
    document.getElementById("movies-collections-container").innerHTML +=
      `<div class="movie-container" id="movie_${movie_imdbID}"></div>`;
}
function updateMovieElement(movie_imdbID, res) {
  let elm = document.getElementById(`movie_${movie_imdbID}`);
  elm.innerHTML = `
    <div class="movie-image">
        <img src=${res.data.Poster} alt="${res.data.Title} Poster">
    </div>

    <div class="movie-content">
        <div class="add-content-container">
            <div>
                <h2 class="movie-name">${res.data.Title}</h2>
                <p class="movie-release-date">Released: ${res.data.Year}</p>
            </div>
        </div>
    </div>
  `;
}

Object.keys(movies_collections).forEach(movies_collection_object => {
    const movies_collections_movies_array = movies_collections[movies_collection_object].movies;

    movies_collections_movies_array.forEach(movie => {
        let movie_imdbID = movie.split("_")[0];

        addMovieElementToContainerForID(movie_imdbID);

        axios.get("https://www.omdbapi.com/?i=" + movie_imdbID + "&apikey=56bdb7b4").then((res) => {
             updateMovieElement(movie_imdbID, res)
        })
    })
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing client-side properties in an onClick event within Next.js framework

class homeNotLoggedIn extends React.Component { componentDidMount() { function logout(){ localStorage.clear() location.reload() } } render() { return ( <div> < ...

Using the .map method to index an array is causing issues in Node.js

Hey everyone, I'm struggling to properly index a JSON array using the map function. It seems like my code isn't quite right. This is what I have: var entireHTMLssssq = lloopmois.map((result, index) => `<div id=${index} style="position: a ...

Trouble arises when attempting to add an image to a spherical object

I've searched through various threads, Googled extensively, watched YouTube tutorials.... But I can't seem to figure out how to apply a texture to my Sphere. When I run this code, all I see is a white Sphere without any texture showing up. Can so ...

Utilize ng-bootstrap in an Angular CLI project by integrating it with npm commands

I've been attempting to set up a project using Angular CLI with ng-bootstrap, but I'm having trouble getting the style to work properly. Here are the exact steps I followed (as outlined in the get-started page): Create a new project using `ng n ...

Is there a way to showcase individual components on a single surface one at a time?

Let me try to explain my issue as clearly as possible! I am currently working on a website using React and Material-UI. On one of my pages, I have a Paper component where I want to display different components that I have created, but only one at a time. ...

Prevent Bootstrap 5 input fields from automatically adjusting to the height of a CSS grid cell

Below is some Bootstrap 5 markup that I need help with. The first example is incorrect. I don't want the Bootstrap input to be the same height as the grid cell. The second example is right, but I want to achieve the same result without using a wrapp ...

Arranging the placement of list-group-item buttons

Looking for a way to create a list-group-item with two buttons that are equal in height and aligned to the right? Take a look at this example below: https://i.sstatic.net/II2nl.png While I have the basic structure in place, I'm having trouble gettin ...

To successfully process this file type in JavaScript, you might require a suitable loader

Currently, I am facing an issue with my MVC application while trying to integrate Bootstrap 5 using Webpack. Despite attempting various workarounds with stage-0, stage-2, and stage-3, none have proven successful for me. I suspect that the problem lies wit ...

The "self" variable in the Node.js prototype object fails to retain the correct context for the callback function

Although I have experience as a developer, I am new to Java Script and Node.js. I have searched through various examples and Stack Overflow answers, but I couldn't find a simple and complete example of a prototypical class with correct 'self&apos ...

The dropdown menu appears when the user clicks on an empty area

How can I ensure that the drop-down menu is only activated when the arrow or the name is clicked? I've tried looking at similar questions but haven't found a solution. Currently, clicking anywhere next to "shop" activates the drop-down. Here&apo ...

Leveraging AngularJS for retrieving the total number of elements in a specific sub array

I'm currently working on a to-do list application using Angular. My goal is to show the number of items marked as done from an array object of Lists. Each List contains a collection of to-dos, which are structured like this: [{listName: "ESSENTIALS", ...

The navigation menu that usually appears on mobile devices is surfacing on desktop screens instead - update: images now

I have recently been working on my website juniorgoldreport.com, which was created using WordPress. The plugin I am using specifically for the mobile nav bar is The functionality and ease of use of this plugin are incredible. The setting to show the toolb ...

Preparing data in the Vuex Store efficiently for an AJAX request

Dealing with a Vuex store that holds around 30 fields has been quite the challenge for me over the past couple of days. I've been struggling to properly gather the data before sending it through an AJAX post method. Being aware of the reactivity of Vu ...

Unusual dark streak beneath the Wordpress emblem

I recently created my website using Wordpress and decided to use a PNG image (140*82 px) as the logo instead of the default "site-title". However, I encountered an unusual issue where a black line appeared just below the image. After checking my "header.ph ...

Struggling to understand why my React Component is failing to render properly

Could there be an issue with how I imported react or am I simply overlooking something small? Any feedback would be greatly appreciated. As a beginner in programming, I may be missing a simple solution that I'm not experienced enough to identify. Than ...

What is the best way to directly serve a static html file from a server using React and Express?

I recently downloaded a visually appealing HTML page with links to necessary CSS and JS files from a website builder. My intention is to use this page as the landing page for my React application. However, I'm unsure of the best approach to achieve th ...

Trouble getting CSS and JavaScript to function properly with HTTPS?

It seems that the css and js files are functioning properly on , but not on . As a novice in web design and javascript, I am struggling to find a solution to this issue. Trying to link the CSS file with "//isdhh.org/css/style.css" has not resolved the pr ...

What could be the reason for my difficulties in retrieving the necessary data from this website with Selenium?

Basically, I've been struggling to interact with the "enter your address" field on a particular website through xpath and selenium. I'm curious as to why this is happening. Detailed Explanation The website in question is this one. It features a ...

CORS blocked the JavaScript Image's request

I am encountering an issue with my code that involves capturing selected divs using the HTML2Canvas library. However, when I try to download the captured image file, it is not working as expected. The error message I keep receiving is "Access to Image at ...

Create the final APK file using Phonegap build directly from your local machine, without the need to

While I've been using Phonegap CLI to develop my android apps and everything has been working well, I encountered an issue when trying to create the final .apk file. I have all the necessary tools - SDK, JDK, Java, and environment variables configure ...