Нужна помощь в сохранении игры в любимые игры пользователя - PullRequest
0 голосов
/ 30 октября 2019

Я получаю сообщение об ошибке при попытке связать сохраненную игру с пользователем, который ее сохраняет. В сообщении об ошибке говорится: «не может прочитать свойство push of undefined»

Пользователь и игра могут быть прочитаны в консоли. Я думаю, что это может иметь какое-то отношение к пользовательской модели во время первоначального создания пользователя, однако я не уверен. Я заметил, что если я попытаюсь console.log(user.favGames), он будет возвращен неопределенным.

Я перепробовал все, что мог придумать, я переписал контроллер примерно 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). Обратите внимание, что когда пользователь создает профиль, нет игр, связанных с его профилем. Я почти уверен, что обращаюсь к фактическому экземпляру данных модели, а не к самой модели. Заранее благодарим за помощь.

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Ваши favGames (а также комментарии) должны быть определены как массивы в пользовательской модели, например:

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 () возвращает обещание, поэтому вам нужно использовать затем block или 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");
  }
}
0 голосов
/ 30 октября 2019

Похоже, нужно проверить, существует ли оно:

User.findById(req.user._id)
  .then(user => {
    if (!Array.isArray(user.favGames)) {
      user.favGames = [];
    }
    user.favGames.push(game);
    user.save();
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...