I am making a social media backend. I save post added by the used in a Post model and user data in a User model. GITHUB_REPO_LINK_AT_END
NOTE: UserSchema have a Schema.TypesOf.ObjectId Reference To POST Model. User_Model_&_Post_Model_are_provided_in_the_end
To get all posts of a particular user, I make a GET request to the route "/post" with body:
{ "id" : "6399d54c00308a2fe0bdf9fc"} //sending user id to fetct all the ID of the post from USER model, so i can then query the POST model for the posts
This the function I am getting problem with:
const getPost = async(req, res)=>{
if(req.body.id){
try {
const user = await User.findById(req.body.id).select('-_id post');
//THIS IS THE PART I NEED HELP WITH-------------------------------------------
const posts = await user.post.map(async(postID) => {
const result = await Post.findById(postID).select('-_id title body');
//console.log(result) THIS PRINTS THE CORRECT OBJ FROM DB
return result; //THIS RETURNS AN EMPTY OBJECT HERE
});
//----------------------------------------------------------------------------
res.status(200).json(posts);
} catch (error) {
console.log(error);
res.status(500).json({message: error.message});
}
}
};
when sending a GET request it returns an empty array with empty objects.//PS: no. of empty obj = actual no. of obj in DB
//This is the response
[{},{},{},{},{},{},{},{},{},{},{}]
{
//This is the user object
"_id": "6399d54c00308a2fe0bdf9fc",
"createdAt": "2022-12-14T13:52:40.483Z",
"name": "ShivamUttam",
"username": "Fadedrifleman",
"post": [
"6399d57200308a2fe0bdfa00",
"6399d5c400308a2fe0bdfa06",
"6399d5ca00308a2fe0bdfa0a",
"6399d5d600308a2fe0bdfa0e",
"6399de29e8aa8697299941c5",
"6399dec6e9b79ac66c59cd7a",
"6399df0dbea937f8b3365979",
"6399df31bea937f8b336597d",
"6399df31bea937f8b3365981",
"6399df32bea937f8b3365985",
"6399df33bea937f8b3365989"
],
"__v": 5
}
Model for USER and POST:
User:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now()
},
name: {
type: String,
required: [true, 'name must be provided'],
},
username : {
type: String,
required: [true, 'Username must be provided'],
},
post:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post',
}],
});
module.exports = mongoose.model('User', userSchema)
Post:
const mongoose = require('mongoose')
const postSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now()
},
title:{
type: String,
required: [true, "title cannot be empty"],
max: [20, "title cannot exceed 20 character"]
},
body: {
type: String,
max: [145, "body cannot exceed 145 character"],
},
tags:{
type: String,
},
});
module.exports = mongoose.model('Post', postSchema);
https://github.com/Fadedrifleman/socialMediaAppBackend/tree/master
CodePudding user response:
Since you have used async callback function in the map method, a async function always return a promise, whatever the entity is returned by the function is wrapped inside a promise and that promise is returned.
If you want to use map function with async js code, you can try the following
const posts = await Promise.all(user.post.map(async(id)=>{
const result = await Post.findById(postID).select('-_id title body');
return result;
}));
and if you want to straightaway send the posts, you can also use .lean() method on posts, as in
await Post.findById(postID).select('-_id title body').lean()
CodePudding user response:
You had some bugs that probably would interfere, I did a pull request to fix them: https://github.com/Fadedrifleman/socialMediaAppBackend/pull/1
But the main part would be this:
const getPost = async (req, res) => {
try {
if (req.body.id) {
const user = await User.findById(req.body.id);
await user.populate("post");
res.status(200).json(user.post);
return;
}
const posts = await Post.find({ access: 'public' }).select('-access');
res.status(200).json(posts);
} catch (error) {
res.status(500).json({ message: error.message });
}
};