Using Firestore Promises to Iterate Through a Collection in a For Loop within Nuxt.js

I have been attempting to replicate a join statement in Firestore by associating a user with a comment through iterating over the comments collection. I am aware that querying a collection results in a promise and response, but I am uncertain about how to iterate over the documents in the response and execute another query within the loop.

Below is a simple example:

asyncData ({ params }) {
  var postRef = Firestore.collection('posts').doc(params.post);
  var commentRef = 
    Firestore.collection('posts').doc(params.post).collection('comments');
    return commentRef.orderBy('created_on', 'desc').get().then(snapshot => {
        var comments = []
        snapshot.forEach(doc => {
            var docData = doc.data()
            comments.push({
                comment: { data: doc.data(), id: doc.id }
            })
        })
        return comments
    })
    .then(data => {
        var comments = []
        for(const comment of data) {
            Firestore.collection('users-public').doc(comment.comment.data.created_by).get()
            .then(doc => {
                console.log('User Found!')
                comments.push( {
                    comment: { data: comment.comment.data, id: comment.comment.id },
                    user: doc.data()
                })
            })
        }
        console.log("Ready to Return!")
        return {comments: comments}
    })
},

During execution, "Ready to Return!" gets logged before "User Found!" since the calls are asynchronous. I attempted using for...of without success. Is there a way to avoid this issue and wait for all async calls to complete before returning? It's crucial for me to resolve the promises to the User collection and use .data() to prevent a circular JSON error.

Answer №1

One effective strategy is to store all promises in an array and then utilize the Promise.all() method. This acts as a wrapper for a collection of promises, triggering the callback once all promises are fulfilled.

If you opt for this approach, your code may resemble the following:

asyncData({ params }) {
    var postRef = Firestore.collection('posts').doc(params.post);
    var commentRef =
        Firestore.collection('posts').doc(params.post).collection('comments');
    return commentRef.orderBy('created_on', 'desc').get().then(snapshot => {
        var comments = []
        snapshot.forEach(doc => {
            var docData = doc.data()
            comments.push({
                comment: { data: doc.data(), id: doc.id }
            })
        })
        return comments
    })
        .then(data => {
            var comments = []
            // Creating an empty array to store promises
            var promises = []
            for (const comment of data) {
                let promise = Firestore.collection('users-public').doc(comment.comment.data.created_by).get()
                // Adding promises to the array
                promises.push(promise)
            }
            // The callback in this method will trigger once all promises in the array are resolved
            Promise.all(promises).then(users => {
                console.log("All users fetched!")
                // users is an array containing results of each user query promise
                users.forEach(user => {
                    let userId = result.id
                    // Assigning user info to every corresponding comment
                    comments.filter(comment => {
                        return comment.comment.data.created_by === userId
                    }).map(comment => {
                        comment.user = user.data()
                    })
                })
                console.log("Returning!")
                return { comments: comments }
            })
        })
}

Alternatively, consider using a library like async to manage asynchronous function flow.

We hope this guidance proves helpful!

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

Tips for postponing the first button event in Vue 3 and JavaScript

My current task involves setting up a button event in Vue 3 that triggers a setTimeout countdown on the button before redirecting to another page. The event function has a conditional statement that initiates a countdown from 5 to 0 as long as the countVal ...

Adjusting the Aspect Ratio of an Embedded YouTube Video

<!DOCTYPE HTML> <head> <style> body { overflow: hidden; margin:0; } </style> </head> <body> <iframe id="video" src="https://www.youtube.com/embed/U4c9bBeUe4M?modestbranding=1&sh ...

"Vercel encounters a read-only file system when trying to change file

Hey folks, I've been using vercel for deploying my project. There's an issue with one of the dependencies in my NextJS project, which is located inside the node_modules folder. This dependency is supposed to read and write files within its own di ...

How can you apply color to {{expression}} text using AngularJS while also keeping all the text on a single line?

After writing the following code, I noticed that when I enter text into the input box, an output appears. However, I am now trying to find a way to color the output text while keeping it on the same line. <script src="https://ajax.googleapis.com/ajax ...

What are the implications of sending xmlhttprequests to a server every second?

Currently in the process of developing a Chrome extension designed to monitor Gmail inbox activity. To retrieve the necessary data, I am utilizing the XML feed URL: For updating purposes, I've integrated the chrome.alarms API to execute a GET reques ...

How can I efficiently extract neighboring characters from a JavaScript array of strings?

Imagine this scenario: We have an array like this: var arr = [ "Exploring the zoo, we saw every kangaroo jump and quite a few carried babies.", "The wizard quickly jinxed the gnomes before they vaporized.", "The quick brown fox jumps over the lazy dog."]; ...

I am encountering an issue where my ejs file is not rendering properly even after moving my static files to the public folder and including the line of code app.use(express.static("public")). Can anyone help

After relocating the index.html and css files to the public folder and adding app.use(express.static("public)) in app.js, everything was working fine and the list.ejs was rendering correctly. However, there seems to be an issue now. const express = re ...

Continuously looping in Firefox on Android is the setInterval function

I have a brief section of JavaScript that I would like to use to check a server every few seconds and update the DOM. function updateCard() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState ...

Retrieving location data using the Google Maps geocoder

Could someone help me with this issue in my code? function getLocationName(latitude, longitude) { if (isNaN(parseFloat(latitude)) || isNaN(parseFloat(longitude))) { return false; } var locationName; var geocoder = new google.maps. ...

The not-found.js file in Next.js is displaying an empty page rather than showing a 404 error message

My current project involves using Next.js v13.4.19 with the app router mode. However, I seem to be facing an issue with the not-found.js page located in the app folder. Whenever a non-existing route is accessed, it does not render a 404 page as expected. ...

"Troubleshooting the issue of nested jQuery Ajax requests failing to execute properly

UPDATE: I'm getting an error saying that my li tag is considered an illegal token. I'm unsure how to resolve this issue as I believed I was appending it within a ul tag I'm tasked with fetching a JSON array of public Github repositories and ...

What could be the reason for my selector ( a:hover ~ a ) not functioning correctly?

My goal is to create a hover effect where hovering over a link will reduce the opacity of other links while keeping the color of the hovered link unchanged. I attempted using a:hover ~ a, but it did not work as expected. I set up a new jsfiddle with a bas ...

Utilizing arrays in JavaScript alongside jQuery's methods such as $.inArray() and .splice()

I am currently dealing with an array that is limited to containing 12 values, ranging from 1 to 12. These values can be in any order within the array. My task is to iterate through the array and identify the first unused value, assigning it to a variable. ...

Is it possible to pass parameters in the .env file in Node.js?

I am storing my file users.env inside routes/querys/users.env module.exports = { GET_USERS: "SELECT * FROM users", CREATE_USER: "INSERT INTO users ("id", "first_name", "last_name", "active") VALUES (NULL, '%PARAM1%', '%PARAM2%', & ...

Guide to displaying a loading progress bar within a div using JQuery

With the help of jQuery's Load function, I am able to load another page into a specific div by calling jQuery.Load("#divid","pageURL"). Whenever I click on an anchor tag within the loaded page, it triggers the jQuery.load("#divid","pageURL") function ...

What is preventing Bootstrap properties from being applied to HTML elements appended to the DOM through JavaScript?

Currently, I am immersed in a project that utilizes Bootstrap to generate various nested components styled in accordance with Bootstrap's class system. I triumphantly crafted a card component using Bootstrap, but encountered a challenge when attemptin ...

What exactly does ".default" signify in Angular, Typescript, or Javascript?

Could someone please clarify the significance of the ".default" in the code snippet below? I am interested in implementing this code in our project, but my understanding of the mentioned code fragment is uncertain. (I have modified my question to display ...

Verify if the dates align in javascript

I am currently in the process of developing a custom ASP.Net validator that verifies whether the input data corresponds to a non-working day. For the purpose of this validation, a "non-working day" is defined as follows: The date falls on either a Satur ...

Having trouble with my React App compiling media files

I'm currently working with create-react-app and using a Data.js file where I define objects with properties that are spread as props in a tag. However, when I run npm start or deploy my application, the image doesn't show up. It seems like the co ...

Ways to conceal a child div element without using any specific ID reference

I encountered an issue where I need to conceal all divs within a parent div except the first one. The challenge is that these divs do not possess any unique identifiers. Is there a way to achieve this task using CSS or pure JavaScript? <div role="list ...