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

Ensuring validity using dynamic context objects within Joi

I need to implement a dynamic validation system that involves downloading an object at runtime and saving it as a well-formed .json file. The objective is to use the values from this downloaded object as part of a validation process using Joi.validate wi ...

Erase data from MySQL database by leveraging React.js and Express

I'm currently facing an issue when trying to delete a post using React and MySQL. Despite not encountering any errors or warnings, the posts do not get deleted. When I check the affected rows using console.log, it returns 0. deleteNote = id => { ...

The process of transferring ViewBag value as a parameter in an AngularJS function

I'm facing an issue where the viewbag value is not being passed as a parameter in ng-init. Can someone guide me on how I can successfully pass the viewbag value as a parameter? angular.js { $scope.detail = function (Id) { ...

Is it possible to utilize a JS script generated within the body or head of an HTML file directly within CSS code?

As a beginner in webpage development, I have a query regarding the technical aspect. Is it possible to utilize variables from a JavaScript function, which is placed either in the head or body of an HTML file, directly in CSS code to make modifications such ...

Solving the Cross-Origin Resource Sharing problem in AngularJS

While using the http dependency in AngularJS and setting headers for CORS, I am encountering an error. Please check the console.log for more information on the error. The error message reads: "XMLHttpRequest cannot load . Response to preflight request doe ...

Tips for updating border color when focused with styled-components

How can I change the border color of an input on focus using styled-components and React? Here is the code snippet I am currently using: import React from "react"; import PropTypes from "prop-types"; import styled from "styled-components"; const String ...

Exploring multipart uploads in Express JS 4: Leveraging body parser and dicer for efficient file handling

Currently, with express 4 and body-parser set up as shown below: var bodyParser = require('body-parser'); ... app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); After integrating dicer, it seems like body parser ...

Transform the C# DateTime to LocalTime on the client side using JavaScript

Utilizing the Yahoo API on my server to retrieve currency information can be done through this link: Yahoo Currency API This API provides me with both a Date and a Time, which I'd like to combine into a single DateTime object. This will allow me to e ...

Guide to sending a JSON-formatted request with the http module in NodeJS

There are two web servers set up: one utilizes the Express.js framework to handle requests and responses, while the other relies on the HTTP module to route requests to the former. The current task at hand is to send requests in JSON format, but there seem ...

differences between using form's get method and sending an angular $http.get request

When trying to make a GET request to a specific URL from my Angular frontend to an ExpressJS backend, I encountered some interesting behavior. In the frontend code snippet below: <li> <a ng-click="givequiz()">GiveQuiz</a> </l ...

What is preventing me from using .bind(this) directly when declaring a function?

Consider the code snippet below: function x() { this.abc = 1; function f1() { alert(this.abc); }.bind(this) var f2 = function b() { alert(this.abc); }.bind(this); } I am curious about how to make the "this" of the out ...

Submitting the Ajax form will result in the quantity of the product in the cart being updated while remaining on

Hello, I am using ajax to keep the user on the same page after submitting a form. If successful, I will use ajax load to load another page that displays the quantity of the product. However, I am facing an issue where each subsequent submit increases the q ...

looping through the iteration

Here is a link to my original plunker demonstration: http://plnkr.co/edit/9UBZ9E4uxAo1TXXghm1T?p=preview. In the case of div 4 (ng-if="show==4"), I am looking for a way to hide the particular div when the list is empty. Currently, each div is displayed fo ...

Exploring the power of Angular by implementing nested ng-repeat functionalities:

I am currently working on an ng-repeat feature to add items from the array (album array). Everything seems to be functioning correctly. However, I also have a colors array that should assign different background-colors to the card elements of the album arr ...

Looking for guidance on implementing throttle with the .hover() function in jQuery?

Seeking a way to efficiently throttle a hover function using jQuery. Despite various examples, none seem to work as intended. The use of $.throttle doesn't throw errors but ends up halting the animation completely. Here is the code snippet in question ...

Angular & Loopback: The function User.login is not recognized

Today, I encountered an error while attempting to execute the Login function in Ionic. An error message popped up stating: TypeError: User.login is not a function (found in controller.js). Here's a snippet from my controller.js : angular.module(&ap ...

Execute either development or production builds in Heroku based on the NODE_ENV variable

I am currently working on a project using react and express for server-side rendering. Here is the layout of my folder structure: root client build node_modules public src package.json node_modules routes server.js package.json In this ...

Is there a way for me to retrieve the UrlMatcher from ui-router?

While exploring the ui-router documentation, I came across an object called UrlMatcher. This object contains useful methods like exec, but I am struggling to find clear instructions on how to access it. Nevertheless, the documentation page provides a detai ...

Encountering an error message of "[jwt is not defined]" when attempting to retrieve data from the MongoDB

Explaining the question - I am successfully registering users in a mongoDB database and generating an accessToken [jwt based]. However, when trying to query the database to fetch the list of users, I encounter the error: jwt is not defined. Also, mentioni ...

Modify two files in separate models with a single request

Imagine I am creating the backend for a Polling app. Users can select an option in a poll, and then a request is sent to update both the poll document and the user's document. // Express endpoint for /vote/:pollId/:optionIndex // (middleware puts use ...