【发布时间】:2020-10-23 22:05:09
【问题描述】:
我正在运行一个 MERN 堆栈应用程序。我有两个系列。 “用户”和“订阅”。注册用户然后尝试添加订阅后,我会收到此错误。
TypeError: Cannot read property '_id' of undefined
[0] at /Users/njboot/web-development/submarine/routes/apiroutes.js:72:45
注册后,该用户已成功添加到数据库“用户”集合中。如果我退出,然后重新登录,我可以添加订阅。如果我首先注册(在第一个会话中),我只是无法添加订阅。
我曾尝试使用 body-parser 中间件而不是 express 以防万一这是问题,但事实并非如此。
这是我的express-config.js:
require("dotenv").config();
// SET EXPRESS ENVIRONMENT
const express = require("express");
const app = express();
// const path = require("path")
// imports session, logger, passport, and path
const middleware = require("../middleware");
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// ADD WINSTON LOGGER MIDDLEWARE TO SERVER
app.use(middleware.logger);
// We need to use sessions to keep track of our user's login status
app.use(
middleware.session({
secret: "sandwich",
resave: true,
saveUninitialized: true,
})
);
app.use(middleware.passport.initialize());
app.use(middleware.passport.session());
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
require("../routes/apiroutes")(app);
module.exports = app;
这是我的apiroutes.js,我在第 72 行发表了一条评论,出现错误:
const middleware = require("../middleware");
const passport = middleware.passport;
const User = require("../models/User");
const API = require("../controller");
const path = require("path");
const scrubUser = userObject => {
let cleanUser = {};
cleanUser.subscriptions = userObject.subscriptions;
cleanUser.firstname = userObject.firstname;
cleanUser.lastname = userObject.lastname;
cleanUser.email = userObject.email;
cleanUser.income = userObject.income;
return cleanUser;
};
module.exports = app => {
// Endpoint to login
app.post("/login", passport.authenticate("local"), (req, res) => {
try {
API.controller.getUser(req.user._id, response => {
return res.json(scrubUser(response));
});
} catch (err) {
throw err;
}
});
app.get("/logout", (req, res) => {
req.logout();
res.send({ result: "success" });
});
// Register User
app.post("/register", (req, res) => {
var password = req.body.password;
var password2 = req.body.password2;
if (password == password2) {
var newUser = new User({
name: req.body.name,
firstname: req.body.firstname,
lastname: req.body.lastname,
email: req.body.email,
income: req.body.income,
username: req.body.username,
password: req.body.password,
});
User.createUser(newUser, (err, user) => {
if (err) throw err;
res.send(user).end();
});
} else {
res.status(500).send('{ errors: "Passwords don\'t match" }').end();
}
});
// Endpoint to get current user
app.get("/api/getuser", (req, res) => {
if (!req.user) return res.json({ result: "no user" });
try {
API.controller.getUser(req.user._id, response => {
return res.json(scrubUser(response));
});
} catch (err) {
throw err;
}
});
app.post("/api/addsub", (req, res) => {
// I GET THE ERROR HERE!
API.controller.addSubscription(req.user._id, req.body, response => {
try {
API.controller.getUser(req.user._id, response => {
return res.json(scrubUser(response));
});
} catch (err) {
throw err;
}
});
});
app.post("/api/removesub", (req, res) => {
API.controller.removeSubscription(req.user._id, req.body.id, response => {
try {
API.controller.getUser(req.user._id, response => {
return res.json(scrubUser(response));
});
} catch (err) {
throw err;
}
});
});
app.all("*", function (req, res) {
res.redirect("https://submarine-sub-tracker.herokuapp.com/");
});
};
这是我的controller:
var mongojs = require("mongojs");
const db = require("../models");
const Controller = {
getUser: (id, callback) => {
db.User.findOne({ _id: mongojs.ObjectId(id) })
.populate("subscriptions")
.then(theUser => callback(theUser));
},
addSubscription: (userId, newSub, callback) => {
console.log(userId);
db.Subscription.create(newSub).then(response => {
db.User.findOneAndUpdate(
{ _id: mongojs.ObjectId(userId) },
{ $push: { subscriptions: response._id } },
{ new: true }
).then(theUser => callback(theUser));
});
},
removeSubscription: (userId, subId, callback) => {
db.User.findOneAndUpdate(
{ _id: mongojs.ObjectId(userId) },
{ $pull: { subscriptions: mongojs.ObjectId(subId) } },
{ new: true }
).then(theUser => callback(theUser));
},
};
module.exports = Controller;
最后是我的server.js:
require("dotenv").config();
const app = require("./config/express-config");
const mongoose = require("mongoose");
const PORT = process.env.PORT || 5000;
const MONGODB_URI =
process.env.MONGODB_URI ||
`mongodb+srv://root:${process.env.PASSWORD}@cluster0.6e0yo.mongodb.net/submarine?retryWrites=true&w=majority`;
// connect to MongoDB
mongoose.connect(MONGODB_URI, { useNewUrlParser: true }, err => {
if (err) {
console.log("There is a problem with the connection" + err);
} else {
console.log("Mongoose connection is good.");
console.log(MONGODB_URI);
}
});
//server is up and running
app.listen(PORT);
这也是护照配置:
var passport = require("passport");
var LocalStrategy = require("passport-local").Strategy;
var User = require("../models/User");
passport.use(
new LocalStrategy(function (username, password, done) {
User.getUserByUsername(username, function (err, user) {
if (err) throw err;
if (!user) {
return done(null, false, { message: "Unknown User" });
}
User.comparePassword(password, user.password, function (err, isMatch) {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: "Invalid password" });
}
});
});
})
);
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
console.log(req.user);
User.getUserById(id, function (err, user) {
done(err, user);
});
});
// Exporting our configured passport
module.exports = passport;
【问题讨论】:
-
正如错误所说,您的 _id 未定义。在你的 api 控制器
console.log(req.user)中告诉我们你得到了什么 -
@HenryLy 所以我在
console.log(req.user)控制器方法中addSubscription并且控制台中没有弹出任何内容。我猜它永远都达不到? -
@HenryLy
console.log(userId)什么都不返回 -
嘿@njboot,req.user 从哪里得到它的值?也许你忘记添加中间件了。
-
@HenryLy 我相信护照
标签: javascript node.js mongodb api express