Home > Blockchain >  MongoDB: How to get and display items by userID
MongoDB: How to get and display items by userID

Time:03-05

I'm trying to get and display all entries in an 'item' collection that contain and are listed by a user/userID from a user collection.

item_controller.js:

const Item = require('../models/item_schema')

const getUserItems = (req, res) => {
    Item.findById(req.params.userID).populate('categoryID').populate('qualityID').populate('userID')
    .then((data) => {
        if (data) {
            res.status(200).json(data)
        } else {
            res.status(404).json(`Item from user id ${req.params.userID} not found.`)
        }
    })
}

module.exports = {
    getUserItems
}

item_schema.js:

const { Schema, model} = require('mongoose')

const itemSchema = new Schema({
    title: {
        type: String,
        required: [true, 'Title field is required.']
    },
    description: {
        type: String,
        required: [true, 'Description field is required.']
    },
    userID: {
        type: Schema.Types.ObjectId,
        ref: "User",
        required: [true, 'User field is required']
    },
    categoryID: {
        type: Schema.Types.ObjectId,
        ref: "Category",
        required: [true, 'Category field is required']
    },
    qualityID: {
        type: Schema.Types.ObjectId,
        ref: "Quality",
        required: [true, 'Quality field is required']
    },
    price: {
        type: Number
    },
    claimed:{
        type: Boolean
    }
}, {
    timestamps: true
})

module.exports = model('Item', itemSchema)

server.js:

const express = require('express')
const cors = require('cors')
const jwt = require('jsonwebtoken')

require('dotenv').config()
require('./db')()

const { getUserItems } = require('./controllers/item_controller')

const port = process.env.PORT || 3000

const app = express()
app.use(cors())
app.use(express.json())

app.use((req, res, next) => {
    if (req.headers && req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
        jwt.verify(req.headers.authorization.split(' ')[1], 'zero_waste_app', (err, decode) => {
            if (err) req.user = undefined
            req.use r = decode
            next()
        })
    } else {
        req.user = undefined
        next()
    }
})

// Item Routes 
app.get('items/user/:userID', getUserItems)

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

I think my problem is in the item_controller, I've tried a few different ways, such as Item.find({userID: userID}) or even hardcoding a userID in Item.find({userID: '620a6299299db14c46a1eb9f'}), but I can't get it to work. Does anyone know what I'm doing wrong and how I can fix it?

Also please do let me know if there's any more information or code I can give that would be helpful.

CodePudding user response:

So, first of all, if you don't specify the primary key, mongoose will automatically generate a _id field in your collections. and this attribute is the one that is used in the "...ById" methods of the collection, like findById, findByIdAndUpdate, etc.

Ok, how it solves your problem? You're using Item.findById method using the value of a userID, but your _id is completely different. You've to use the .find method passing the userID attribute, also you don't need to chain the populate methods, you can populate many fields in only one method call.

Try to change your controller to this:

const {userID} = req.params; 
Item
    .find({userID})
    .populate('categoryID qualityID userID')
    .then((data) => {
        if (data) {
            return res.status(200).json(data)
        }
        return res.status(404).json(`Item from user id ${req.params.userID} not found.`)
        
    })

CodePudding user response:

I figured it out.

const getUserItems = (req, res) => {

    Item.find({userID: req.params.userID}).populate('categoryID').populate('qualityID')
    .then((data) => {
        if (data) {
            res.status(200).json(data)
        } else {
            res.status(404).json(`Item from user id ${req.params.userID} not found.`)
        }
    })
}

also my route was missing a '/' at the beginning, so:

app.get('/items/user/:userID', getUserItems)

and not what I previosly had:

app.get('items/user/:userID', getUserItems)
  • Related