【问题标题】:MERN stack, express error - "TypeError: Cannot read property '_id' of undefined" at apiroutesMERN 堆栈,表示错误 - apiroutes 处的“TypeError:无法读取未定义的属性 '_id'”
【发布时间】: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


【解决方案1】:

【讨论】:

    猜你喜欢
    • 2017-11-05
    • 2020-09-03
    • 1970-01-01
    • 2013-09-03
    • 2022-07-27
    • 1970-01-01
    • 2020-03-06
    • 2019-09-13
    • 1970-01-01
    相关资源
    最近更新 更多