【问题标题】:Need help saving a game to a user's favorited games需要帮助将游戏保存到用户喜爱的游戏
【发布时间】:2020-02-25 23:46:24
【问题描述】:

我在尝试将已保存的游戏与保存它的用户关联时收到错误消息。错误说“无法读取未定义的属性推送”

可以在控制台中读取用户和游戏。我认为这可能与初始创建用户期间的用户模型有关,但我不能确定。我确实注意到,如果我尝试console.log(user.favGames),它将返回 undefined。

我已经尝试了所有我能想到的方法,我已经重写了大约 10 次控制器,但无济于事。

用户模型

const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const SALT_ROUNDS = 6

const Schema = mongoose.Schema

const userSchema = new Schema(
  {
    username: { type: String, unique: true },
    email: { type: String, unique: true, unique: true },
    password: { type: String, required: true },
    avatar: { type: String },
    favGames: { type: Schema.Types.ObjectId, ref: 'Game', default: null },
    comments: { type: Schema.Types.ObjectId, ref: 'Comment', default: null }
  },
  {
    timestamps: true
  }
)

userSchema.set('toJSON', {
  transform: function(doc, ret) {
    delete ret.password
    return ret
  }
})

userSchema.pre('save', function(next) {
  const user = this
  if (!user.isModified('password')) return next()
  bcrypt.hash(user.password, SALT_ROUNDS, function(err, hash) {
    if (err) return next()
    user.password = hash
    next()
  })
})

userSchema.methods.comparePassword = function(tryPassword, cb) {
  bcrypt.compare(tryPassword, this.password, cb)
}

module.exports = mongoose.model('User', userSchema)

游戏模型

const mongoose = require('mongoose')

const Schema = mongoose.Schema

let gameSchema = new Schema({
  name: { type: String, required: true },
  boxArtUrl: { type: String, required: true },
  twitchID: { type: String, required: true },
  comments: { type: Schema.Types.ObjectId, ref: "Comment"}
})

module.exports = mongoose.model('Game', gameSchema)

游戏路由器

const express = require('express')
const router = express.Router()

const gamesCtrl = require('../../controllers/gameCtrl')

function isAuthed(req, res, next) {
  if (req.user) return next()
  return res.status(401).json({ msg: 'Unauthorized ' })
}

router.get('/')
router.post('/', isAuthed, gamesCtrl.addGame)

module.exports = router

游戏控制器

const User = require('../models/user')
const Game = require('../models/Game')

function addGame(req, res) {
  Game.create({
    name: req.body.name,
    twitchID: req.body.id,
    boxArtUrl: req.body.box_art_url
  })
    .then(game => {
      User.findById(req.user._id)
        .then(user => {
          console.log(game)
          console.log(user.favGames)
          // user.favGames.push(game)
          // user.save()
        })
        .catch(err =>
          console.log('error when updating user with new game', err)
        )
    })
    .catch(err => console.log('error saving game', err))
}

module.exports = {
  addGame
}

错误在我的控制器中标记为user.favGames.push(game)。请注意,当用户创建个人资料时,没有与他们的个人资料关联的游戏。我很确定我调用的是模型的实际数据实例,而不是模型本身。提前感谢您的帮助。

【问题讨论】:

    标签: reactjs mongodb express mongoose


    【解决方案1】:

    您的 favGames(以及 cmets)必须像这样在用户模型中定义为数组。

    const userSchema = new Schema(
      {
        username: { type: String, unique: true },
        email: { type: String, unique: true, unique: true },
        password: { type: String, required: true },
        avatar: { type: String },
        favGames: [{ type: Schema.Types.ObjectId, ref: 'Game', default: null }],
        comments: [{ type: Schema.Types.ObjectId, ref: 'Comment', default: null }]
      },
      {
        timestamps: true
      }
    )
    
    

    还有 user.save() 返回一个 promise,所以你需要使用 then 阻塞,或者 await。

    所以addGame函数一定是这样的(我把代码转换成async/await)

    async function addGame(req, res) {
      try {
        let game = await Game.create({
          name: req.body.name,
          twitchID: req.body.id,
          boxArtUrl: req.body.box_art_url
        });
    
        let user = await User.findById(req.user._id);
    
        if (user) {
          user.favGames.push(game);
          await user.save();
          res.status(200).send("game and user saved");
        } else {
          console.log("user not found");
          res.status(404).send("user not found");
        }
      } catch (err) {
        console.log("Err: ", err);
        res.status(500).send("Something went wrong");
      }
    }
    

    【讨论】:

    • req.user._id 在中间件中,所以我应该很好。我正在使用 JWT 进行身份验证。让我试试你的异步等待实现。此外,您在用户模式中是正确的,完全忽略了这一点。
    • @SalvatoreArgentieri 是否与 User.findById(req.user_id) 一起使用?
    • 嘿,只是能够坐下来实施您的建议。它确实适用于 req.user._id。我已经设置好了,所以我可以从发送到服务器的请求中提取整个用户对象(认为这样会使事情变得更简单一些)。谢谢您的帮助!对于任何查看这篇文章的人,我认为使用异步等待方法修复了它。再次感谢@SuleymanSah 的协助
    【解决方案2】:

    看起来这是一个检查它是否存在的问题:

    User.findById(req.user._id)
      .then(user => {
        if (!Array.isArray(user.favGames)) {
          user.favGames = [];
        }
        user.favGames.push(game);
        user.save();
      })
    

    【讨论】:

    • 不幸的是,我仍然收到同样的错误。几乎认为 user.favGames 完全不存在
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 2016-06-25
    相关资源
    最近更新 更多