0
const returnPostData = async (req, res, initialPostsQueryArray) => {
    try{
        const promises = initialPostsQueryArray.map( async (post) => {
            let voteCount = 0;
            let voted = false;
            let liked = false;
            let userHandle;
            let userImageUrl;
            let votingOptionsDictionary;
            let userVoteOption;

            voteCount = sumValues(post.voting_options);
            pool.query('SELECT userhandle, image_url FROM users WHERE id = $1 ', 
                [post.user_id], 
                (error, results) => {
                    if (error) {
                        console.log(error);
                        return res.json({'Error': error.detail});
                    }
                    const userPostquery = results.rows[0];
                    userHandle = userPostQuery.userhandle;
                    userImageUrl = userPostQuery.image_url;
                    pool.query('SELECT EXISTS( SELECT 1 FROM likes WHERE user_id = $1 AND post_id = $2)', 
                        [req.user.userId, post.post_id], 
                        (error, results) => {
                            if (error) {
                                console.log(error);
                                return res.json({'Error': error.detail});
                            }
                            // if the user like exists, set liked = true
                            if(results.rows[0].exists == true){
                                liked = true;
                            }
                            pool.query('SELECT EXISTS( SELECT 1 FROM votes WHERE user_id = $1 AND post_id = $2)',
                                [req.user.userId, post.post_id],
                                (error, results) => {
                                    if (error) {
                                        console.log(error);
                                        return res.json({'Error': error.detail});
                                    }
                                    // if the user vote exists, set voted = true and query for what they voted for
                                    if(results.rows[0].exists == true){
                                        voted = true;
                                        votingOptionsDictionary = post.voting_options;
                                        pool.query('SELECT voting_option FROM votes WHERE user_id = $1 AND post_id = $2', 
                                            [req.user.userId, post.post_id], 
                                            (error, results) => {
                                                if (error) {
                                                    console.log(error);
                                                    return res.json({'Error': error.detail});
                                                }
                                                userVoteOption = results.rows[0].voting_option;
                                        });
                                    }
                                    // i dont need voteCount here because that is calculated after the first query, this gets all the counts of the posts
                                    pool.query('SELECT posts.post_id, ' +
                                        'COALESCE( likes.cnt, 0 ) AS like_count ,' +
                                        'COALESCE( comments.cnt, 0 ) AS comment_count ,' +
                                        'COALESCE( shares.cnt, 0 ) AS share_count ' +
                                        'FROM posts ' +
                                        'LEFT JOIN ( SELECT post_id, COUNT(*) AS cnt FROM likes GROUP BY post_id ) likes ON posts.post_id = likes.post_id ' +
                                        'LEFT JOIN ( SELECT post_id, COUNT(*) AS cnt FROM comments GROUP BY post_id ) comments ON posts.post_id = comments.post_id ' +
                                        'LEFT JOIN ( SELECT post_id, COUNT(*) AS cnt FROM shares GROUP BY post_id ) shares ON posts.post_id = shares.post_id ' +
                                        'WHERE posts.post_id = $1',
                                        [post.post_id],
                                        (error, results) => {
                                            if (error) {
                                                console.log(error);
                                                return res.json({'Error': error.detail});
                                            }
                                            const countQuery = results.rows[0];

                                            // final response once all above queries are done, i dont account for thread comments in comment count rn, later problem
                                            return {
                                                postId: post.post_id,
                                                userHandle: userHandle,
                                                userImageUrl: userImageUrl,
                                                postQuestion: post.post_question,
                                                imageUrl: post.post_image_url,
                                                postDescription: post.post_description,
                                                votingOptions: Object.keys(post.voting_options),
                                                voted: voted,
                                                userVoteOption: userVoteOption,
                                                liked: liked,
                                                votingOptionsDictionary: votingOptionsDictionary,
                                                voteStat: voteCount,
                                                likeCount: parseInt(countQuery.like_count),
                                                shareCount: parseInt(countQuery.share_count),
                                                commentCount: parseInt(countQuery.comment_count),
                                                createdAt: post.created_at
                                            };
                                    });
                            });
                    });
            });
        });
        const postData = await Promise.all(promises);
        return res.json(postData);
    }
    catch(e){
        return res.json(e)
    }
}

I'm trying to return an array of the postData for each post. For some reason it keeps on printing null for these objects because the return res.json is somehow running before the promises are even done. Any help is appreciated.

I had this problem before and used the same code, but it didn't work for this one for some reason.

1 Answer 1

2

You're still not using promises but pass callbacks to query. You cannot return from those, and they won't be awaited by Promise.all. You are looking for

async function returnPostData(req, res, initialPostsQueryArray) {
    try{
        const promises = initialPostsQueryArray.map( async (post) => {
            const voteCount = sumValues(post.voting_options);
            const results = await pool.query(
                'SELECT userhandle, image_url FROM users WHERE id = $1 ', 
                [post.user_id],
            ]);
            const userPostquery = results.rows[0];
            const userHandle = userPostQuery.userhandle;
            const userImageUrl = userPostQuery.image_url;
            
            const {rows: likes } = await pool.query(
                'SELECT EXISTS( SELECT 1 FROM likes WHERE user_id = $1 AND post_id = $2)',
                [req.user.userId, post.post_id],
            );
            // if the user like exists, set liked = true
            const liked = likes[0].exists;

            const {rows: votes} = await pool.query(
                'SELECT EXISTS( SELECT 1 FROM votes WHERE user_id = $1 AND post_id = $2)',
                [req.user.userId, post.post_id]
            );
            // if the user vote exists, set voted = true and query for what they voted for
            const voted = votes[0].exists;
            if (voted) {
                votingOptionsDictionary = post.voting_options;
                const { rows } = await pool.query(
                    'SELECT voting_option FROM votes WHERE user_id = $1 AND post_id = $2', 
                    [req.user.userId, post.post_id]
                );
                userVoteOption = rows[0].voting_option;
            }

            // i dont need voteCount here because that is calculated after the first query, this gets all the counts of the posts
            const {rows: posts } = await pool.query(
                `SELECT
                   posts.post_id,
                   COALESCE( likes.cnt, 0 ) AS like_count,
                   COALESCE( comments.cnt, 0 ) AS comment_count,
                   COALESCE( shares.cnt, 0 ) AS share_count
                 FROM posts
                 LEFT JOIN (
                   SELECT post_id, COUNT(*) AS cnt
                   FROM likes
                   GROUP BY post_id
                 ) likes ON posts.post_id = likes.post_id
                 LEFT JOIN (
                   SELECT post_id, COUNT(*) AS cnt
                   FROM comments
                   GROUP BY post_id
                 ) comments ON posts.post_id = comments.post_id
                 LEFT JOIN (
                   SELECT post_id, COUNT(*) AS cnt
                   FROM shares
                   GROUP BY post_id
                 ) shares ON posts.post_id = shares.post_id
                WHERE posts.post_id = $1`,
                [post.post_id],
              );
            const countQuery = posts[0];

            // final response once all above queries are done, i dont account for thread comments in comment count rn, later problem
            return {
                postId: post.post_id,
                userHandle: userHandle,
                userImageUrl: userImageUrl,
                postQuestion: post.post_question,
                imageUrl: post.post_image_url,
                postDescription: post.post_description,
                votingOptions: Object.keys(post.voting_options),
                voted: voted,
                userVoteOption: userVoteOption,
                liked: liked,
                votingOptionsDictionary: votingOptionsDictionary,
                voteStat: voteCount,
                likeCount: parseInt(countQuery.like_count),
                shareCount: parseInt(countQuery.share_count),
                commentCount: parseInt(countQuery.comment_count),
                createdAt: post.created_at
            };
        });
        const postData = await Promise.all(promises);
        return res.json(postData);
    }
    catch(e){
        return res.json(e)
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I really appreciate it! Worked perfectly. I also didn't know how to multiline queries until now. I knew the + strings were a waste lol

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.