0

i'm facing a problem that i'm not able to solve, i've created an express API with mongoose, with 2 models "Posts" and "users"

what i want is that if i perform a GET request to /posts return a lists of posts with the related author, and if i perform a GET request to /users return a lists of users with the related posts

well, the first one works fine, the "authors" is populated correctly.

the second one return always the "posts" array empty.

here my posts model:

const mongoose = require('mongoose')

const PostsModel = new mongoose.Schema({
    title: {
        type: String,
        required: true,
    },
    content: {
        type: String,
        required: true,
    },
    img: {
        type: String,
        required: false,
        default: 'https://picsum.photos/1920/1080',
    },
    author: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'userModel',
    },
    rate: {
        type: Number,
        required: false,
    },
}, { timestamps: true, strict: true });

module.exports = mongoose.model('postsModel', PostsModel, 'posts');

and here my Users model:

const mongoose = require('mongoose');


const UserSchema = new mongoose.Schema({
    firstName: {
        type: String,
        required: true,
        max: 255
    },
    lastName: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        required: true,
    },
    password: {
        type: String,
        required: true,
    },
    role: {
        type: String,
        required: false,
        default: 'user'
    },
    age: {
        type: Number,
        required: false,
        default: 0
    },
    posts: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'postsModel',
    }],
}, {
    timestamps: true, strict: true
})

module.exports = mongoose.model('userModel', UserSchema, 'users' )

and here the respective GET

router.get('/posts', async (req, res) => {
    const {page = 1, pageSize = 10} = req.query
    try {
        const post = await PostsModel.find()
            .populate('author', 'firstName lastName age email')
            .limit(pageSize)
            .skip((page - 1) * pageSize)

        const totalPosts = await PostsModel.count();

        res.status(200).send({
            count: totalPosts,
            currentPage: +page,
            totalPages: Math.ceil(totalPosts / pageSize),
            statusCode: 200,
            post
        })
    } catch (error) {
        res.status(500)
            .send({
                statusCode: 500,
                message: 'Errore interno del server'
            })
    }
})
router.get('/users',  async (req, res) => {
    const { page = 1, pageSize = 30 } = req.query
    try {
        const users = await UsersModel.find()
            .populate('posts', 'title content')
            .limit(pageSize)
            .skip((page - 1) * pageSize)

        const totalUsers = await UsersModel.count()

        res.status(200).send({
            count: totalUsers,
            currentPage: page,
            totalPages: Math.ceil(totalUsers / pageSize),
            pageSize,
            users
        })
    } catch (error) {
        res.status(500)
            .send({
                message: 'Errore interno del server'
            })
    }
})

All seems correct but for some reason, i get always the array empty.

8
  • First of all, shouldn't the PostsModel be PostsSchema? Commented May 26, 2023 at 9:38
  • Ok but this not help…you the reference is correct at least Commented May 26, 2023 at 9:46
  • Can you check the user collection to see if there is a posts array field and does it contains the user._id list? Commented May 26, 2023 at 9:59
  • yes i push, this is my post jsfiddle.net/vdy53ewk @Lin Du i get only an empty array Commented May 26, 2023 at 10:37
  • and here my users post jsfiddle.net/7Lk9nwqp Commented May 26, 2023 at 10:43

2 Answers 2

1

Your routes and models seems to be ok. I guess you are not adding the post._id to the user.posts array when you create the Post. If you add the created post._id to the user posts correctly, it should work.

The code should be something like this:

    const newPost = await PostsModel.create(req.body);

    const userPush = await UsersModel.findByIdAndUpdate(req.body.author, {
        $push: {
            posts: newPost._id,
        },
    });
Sign up to request clarification or add additional context in comments.

1 Comment

following your suggestion i get alwayt the empty array, heres the try that i've made jsfiddle.net/51hcnosy
0

I've found a solution by myself, if someone need the answer is:

in the userSchema simply add:

posts: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'postsModel',
        default: []
    }]

and then when the new post is created

router.post('/posts/new', async (req, res) => {
    const user = await UsersModel.findOne({ _id: req.body.author });

    const newPost = new PostsModel({
        title: req.body.title,
        content: req.body.content,
        author: user._id,
        img: req.body.img,
        rate: req.body.rate,
    })


    try {
        const post = await newPost.save()
        await UsersModel.updateOne({ _id: user._id }, {$push: {posts: post }})
        res.status(200)
            .send({
                message: 'Post salvato correttamente',
                statusCode: 200,
                post
            })
    } catch(error) {
        res.status(500)
            .send({
                message: 'Errore interno del server',
                statusCode: 500
            })
    }
})

1 Comment

This is effectively the same as my answer. You just used updateOne instead of findByIdAndUpdate which does the same.

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.