I'm currently building an application that logs poker statistics. Users create players and then populate games with those players.
I have a games model which references the players from the player model:
const gameSchema = new mongoose.Schema({
firstPlace: { type: mongoose.Schema.ObjectId, ref: 'Players', required: true },
secondPlace: { type: mongoose.Schema.ObjectId,ref: 'Players', required: true },
thirdPlace: { type: mongoose.Schema.ObjectId, ref: 'Players', required: true },
fourthPlace: { type: mongoose.Schema.ObjectId, ref: 'Players' },
fifthPlace: { type: mongoose.Schema.ObjectId, ref: 'Players' },
sixthPlace: { type: mongoose.Schema.ObjectId, ref: 'Players' },
seventhPlace: { type: mongoose.Schema.ObjectId, ref: 'Players' },
eighthPlace: { type: mongoose.Schema.ObjectId, ref: 'Players' },
ninthPlace: { type: mongoose.Schema.ObjectId, ref: 'Players' },
buyIn: { type: Number, required: true },
firstPrize: { type: Number, required: true },
secondPrize: { type: Number, required: true },
thirdPrize: { type: Number, required: true },
date: { type: String },
notes: { type: String },
userId: { type: mongoose.Schema.ObjectId, ref: 'Users', required: true },
})
To get the information on a single game, I populate the references to players -
// Get single Game
async function getSingleGame(req, res, next) {
try {
const { gameId } = req.params
const foundGame = await Games.findById(gameId)
.populate('userId')
.populate('firstPlace')
.populate('secondPlace')
.populate('thirdPlace')
.populate('fourthPlace')
.populate('fifthPlace')
.populate('sixthPlace')
.populate('seventhPlace')
.populate('eighthPlace')
.populate('ninthPlace')
if (!foundGame) throw new NotFound()
return res.status(200).json(foundGame)
} catch (err) {
next(err)
}
}
This works well, so for example firstPlace
is populated with an object that contains all the information of that player.
However, I have a virtual field on my user model which gets all the games that user has created. Code below -
userSchema
.virtual('addedGames', {
ref: 'Games',
localField: '_id',
foreignField: 'userId',
})
.get(function (addedGames) {
if (!addedGames) return
return addedGames.map((game) => {
return {
_id: game._id,
firstPlace: game.firstPlace,
secondPlace: game.secondPlace,
thirdPlace: game.thirdPlace,
fourthPlace: game.fourthPlace,
fifthPlace: game.fifthPlace,
sixthPlace: game.sixthPlace,
seventhPlace: game.seventhPlace,
eigthPlace: game.eigthPlace,
ninthPlace: game.ninthPlace,
buyIn: game.buyIn,
firstPrize: game.firstPrize,
secondPrize: game.secondPrize,
thirdPrize: game.thirdPrize,
}
})
})
This works - but all the placings are objectIds
rather than the objects themselves. My question is - how can I populate these references to Players
on this virtual field?
Thanks in advance, I've been pulling my hair out over this!
After much trial and error, I added this to populate the nested objects -
let user = await User.findById(currentUserId)
.populate('addedPlayers')
.populate([
{
path: 'addedGames',
populate: {
path: 'firstPlace secondPlace thirdPlace fourthPlace fifthPlace sixthPlace seventhPlace eighthPlace',
},
},
])
Originally I just had populate('addedGames')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.