Issue with adding object to array using forEach() function

As I navigate my way through an express route, I am puzzled as to why the "purchasedCards" array turns out empty after going through these database calls. Despite successfully gathering all the necessary information from various DB Queries and placing it in the context for frontend transmission, the object just won't get pushed into the array...

This is my first time exploring the postgres database / SQL realm. Any pointers or suggestions would definitely be welcomed.

    //User Account
router.get('/account', isLoggedIn, (req, res) => {
  //Get User Info - First get the user info
  db.query(`SELECT * FROM users WHERE userid = '${res.locals.user.id}';`)
  .then(user => {
    //Get user Purchases
    db.query(`SELECT * FROM purchases WHERE newowner = '${res.locals.user.id}';`)
    .then(purchases => {
      let purchasedCards = []
      //Get Card Info for Each Purchase
      purchases.forEach( purchasedCard => {
        //Get the card from user_cards table for standard card info.
        db.query(`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`)
        .then( card => {
          //Get Old Owner Info
          db.query(`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`)
          .then(oldOwner => {
            let cardUpdator = {
              cardName: card[0].name,
              cardGame: card[0].game,
              cardOldOwner: oldOwner[0].screen_name,
              cardPID: purchasedCard.purchaseid,
              cardTotal: purchasedCard.total,
              cardId: purchasedCard.card,
            }
            purchasedCards.push(cardUpdator)
          })
        })
      })
      let context = {
        name: user[0].screen_name,
        email: user[0].email,
        purchases: purchasedCards,
      }
      res.render('MyAccount.hbs', context) 
    })
  })
})

Answer №1

To ensure the completion of asynchronous operations, it is recommended to utilize promises and make use of async/await for cleaner code.

//User Account
router.get('/account', isLoggedIn, async (req, res) => {
    //Get User Info - First get the user info
    let user = await db.query(`SELECT * FROM users WHERE userid = '${res.locals.user.id}';`)
    let purchases = await db.query(`SELECT * FROM purchases WHERE newowner = '${res.locals.user.id}';`)
    //Get Card Info for Each Purchase
    let purchasedCardsPromises = purchases.map(async (purchasedCard) => {
        //Get the card from user_cards table for standard card info.
        let [card, oldOwner] = await Promise.all([  db.query(`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`),
                                                    db.query(`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`)])
        let cardUpdator = {
            cardName: card[0].name,
            cardGame: card[0].game,
            cardOldOwner: oldOwner[0].screen_name,
            cardPID: purchasedCard.purchaseid,
            cardTotal: purchasedCard.total,
            cardId: purchasedCard.card,
        }
        return cardUpdator;
    })
    let purchasedCards = await Promise.all(purchasedCardsPromises)
    let context = {
    name: user[0].screen_name,
    email: user[0].email,
    purchases: purchasedCards,
    }
    res.render('MyAccount.hbs', context)
})

Consider using the async/await version provided above to enhance the readability and efficiency of your code.

Answer №2

Consider using async/await to avoid multiple callbacks. The reason for the unexpected behavior is due to attempting to access purchasedCards before it's populated. JavaScript operates asynchronously by default, so at the moment of accessing purchasedCards, the promise has not yet been resolved.

If you wish, here's a suggestion that incorporates async/await. Hopefully, this approach will be beneficial.

async function getPurchasedCards(purchases) {
  const purchasedCards = [];
  return purchases.forEach(async (purchasedCard) => {
    // Obtain card information from user_cards table.
    const card = await db.query(`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`);
    
    // Obtain old owner info.
    const oldOwner = await db.query(`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`);
    
    let cardUpdater = {
      cardName: card[0].name,
      cardGame: card[0].game,
      cardOldOwner: oldOwner[0].screen_name,
      cardPID: purchasedCard.purchaseid,
      cardTotal: purchasedCard.total,
      cardId: purchasedCard.card,
    };
    
    purchasedCards.push(cardUpdater);
    
    if (purchasedCards.length === purchases.length) return purchasedCards;
  });
}

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

transmit URL parameters to Express using Angular 2

I have implemented an Angular service to retrieve data from Express: getRestaurants(districtId) : Observable<void[]>{ let params: URLSearchParams = new URLSearchParams(); params.set('id', districtId); return this.http.get(this.url, ...

Express does not respond to a blank request and the client is left wondering on separate ports without a reply

I am facing an issue with my small react client and express server setup. The react client runs on port 3000 while the express server runs on port 3001. Whenever I click a button, a request is sent to the server. However, the POST request seems to print an ...

What is the best way to access elements and attributes from a specific JSON file?

Is there a way to access each property within the JSON data provided? Additionally, I am interested in filtering specific objects based on their IDs. How can this be achieved using the array.filter method in JavaScript? { "records": [ ...

The size of jVectorMap is displayed too diminutive

Why isn't my jVectorMap adjusting to the new height I've specified for the containing div? It only displays at the default height of 54px. Within a document.ready function in my scripts.js file, I have the following code: $('#team-map-usa& ...

How can I tally the frequency of characters in a given string using Javascript and output them as numerical values?

I am in the process of tallying the frequency of each individual character within a given string and representing them as numbers. For example, let's consider the string "HelloWorld". HELLOWORLD There is one H - so 1 should be displayed with H remov ...

How can I adjust the transparency in a JavaScript popup modal window for an ASP.Net GridView?

Recently, I added an 'onclick' event to every row of an asp gridview and the popup window that appears is functioning perfectly. Now, I'm interested in adding a transparency level to the body of the popup window for a translucent effect. Can ...

How can I retrieve the input value on the current page using PHP?

Hey there, so I'm pretty new to PHP and I have a question. Is it possible to retrieve the input value from an existing input field on a page using PHP when the page loads, and then assign that value to a variable? For instance, let's say I have ...

Styling tables within HTML emails for Gmail and then utilizing PHPMailer to send the emails

I've been racking my brain over this for hours with no luck! Objective: Implementing inline styles for table, td, th, p elements in an HTML email intended for Gmail using PHPMailer. Challenge: Inline styles not being rendered HTML Snippet: <sec ...

Identifying the Operating System of Your Device: iOS, Android or Desktop

I am in need of displaying different app download links based on the user's operating system. This includes IOS, Android, or both if the user is accessing the page on a Desktop device. I am currently utilizing React and Next.js for this project. Unfor ...

An error occurred with Express and Passport: ['ERR_HTTP_HEADERS_SENT']

Currently, I am diving into an ebook tutorial and have encountered a roadblock in a particular piece of code. The code is designed to take a username and password in JSON format through Insomnia or Postman, and it should return a login success cookie. Howe ...

Refine your search by name following the implementation of a character-altering filter

Encountered a scenario in which there is a need to filter elements generated by the 'ng-repeat' directive. I have implemented a custom filter that replaces one character with another and vice versa for each element created. However, when attempt ...

Working with JSON in AJAX with Javascript and C# to handle array data

When attempting to send an array via AJAX using JSON, I am encountering a problem where my C# handler is unable to properly handle the query. It seems that the querystrings are merging together inexplicably. In the scenario presented here, I am trying to ...

jQuery encountering TypeError while attempting to retrieve JSON data

Attempting to retrieve JSON data from the following URL using the provided code snippet: $.ajax({ type: "GET", url: "https://covid.ourworldindata.org/data/owid-covid-data.json/", success: function (data) { $("h5").e ...

Prevent any screen interactions by disabling clicks, and then re-enable them either after a set amount of

My app uses PhoneGap and jQuery Mobile. The issue I am facing is that when I navigate from page A to page B with a single click, everything works fine. However, if I accidentally double-click on page A and move to the next screen (page B) before it's ...

When converting to a React Functional Component using Typescript, an error occurred: The property 'forceUpdateHandler' could not be found on the type 'MutableRefObject<Spinner | null>'

Looking to convert the App component in this CodePen into a Functional component using Typescript. Encountering an error when attempting to run it: ERROR in src/App.tsx:13:14 TS2339: Property 'forceUpdateHandler' does not exist on type 'Mu ...

Expand the data retrieved from the database in node.js to include additional fields, not just the id

When creating a login using the code provided, only the user's ID is returned. The challenge now is how to retrieve another field from the database. I specifically require the "header" field from the database. Within the onSubmit function of the for ...

Having issues updating table with Javascript after form submit in IE and Edge browsers

My current setup involves using Contact Form 7 in Wordpress to store data in a MySQL Database with Submit-Form. Now, I am working on reloading a table containing this data after the form submission. Here is the script I am currently using: /* FORM RELOAD ...

Switch videos within the video tag as you scroll

I am trying to implement a video tag within a div element on my website. Here is the current code: <div class="phone" align="center"> <div class="phone-inner"> <video width="100%" height="100%" autoplay="" loop="" muted id="phonevideo ...

Display loading icon in AngularJS during template retrieval

Imagine I have this specific directive: angular .module('app.widgets') .directive('myCalendarRange', myCalendarRange); function myCalendarRange () { var directive = { link: link, templateUrl: '/template/is/located ...

What could be causing an error when trying to access a property of a database query output in one system but not in

Obtaining the result of a select query using max is currently returning NULL to me. The line var maxLevel = max[0].level; is causing an error in one system with the message "Cannot read property 'level' of undefined", but no such error occurs in ...