简体   繁体   中英

NodeJS posts.findOne(... Is returning 404 not found

I am putting together a blog from NodeJs, Pug, Express, Monk, etc and having trouble retrieving a single post from the db. I keep getting a 404 not found error. I am not sure what I am doing wrong but if you can scan my code and see if I am missing something, I would sure appreciate it.

posts.js

var express = require("express");
var router = express.Router();
var multer = require("multer");
var upload = multer({ dest: "./public/images" });
var mongo = require("mongodb");
var db = require("monk")("localhost/nodeblog");

router.get("/show/:id", function (req, res, next) {
  var posts = db.get("posts");

  posts.findOne({ '_id': req.params.id }, function (err, post) {
    res.render("show", {
      'post': post
    });
  });
});

app.js

var express = require("express");
var path = require("path");
var favicon = require("serve-favicon");
var logger = require("morgan");
var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var session = require("express-session");
var multer = require("multer");
var upload = multer({ dest: "./public/images" });
var expressValidator = require("express-validator");

var mongo = require("mongodb");
var db = require("monk")("localhost/nodeblog");

var routes = require("./routes/index");
var posts = require("./routes/posts");
var categories = require("./routes/categories");

var app = express();

app.locals.moment = require("moment");

app.locals.truncateText = function(text, length) {
  var truncatedText = text.substring(0, length);
  return truncatedText;
};

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));

// Express Session
app.use(
  session({
    secret: "secret",
    saveUninitialized: true,
    resave: true
  })
);

// Express Validator
app.use(
  expressValidator({
    errorFormatter: function(param, msg, value) {
      var namespace = param.split("."),
        root = namespace.shift(),
        formParam = root;

      while (namespace.length) {
        formParam += "[" + namespace.shift() + "]";
      }
      return {
        param: formParam,
        msg: msg,
        value: value
      };
    }
  })
);

// Connect-Flash
app.use(require("connect-flash")());
app.use(function(req, res, next) {
  res.locals.messages = require("express-messages")(req, res);
  next();
});

// Make our db accessible to our router
app.use(function(req, res, next) {
  req.db = db;
  next();
});

app.use("/", routes);
app.use("/posts", posts);
app.use("/categories", categories);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error("Not Found");
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get("env") === "development") {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render("error", {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render("error", {
    message: err.message,
    error: {}
  });
});

module.exports = app;

categories.js index.js and posts.js are all inside the routes folder. Inside the views folder, I have addcategory.pug, addpost.pug, error.pug, index.pug, layout.pug and show.pug If you need to see any of those, please let me know and I will edit this query. Thank you.

index.js

var express = require("express");
var router = express.Router();
var mongo = require("mongodb");
var db = require("monk")("localhost/nodeblog");

/* GET home page. */
router.get("/", function(req, res, next) {
  var db = req.db;
  var posts = db.get("posts");
  posts.find({}, {}, function(err, posts) {
    res.render("index", { posts: posts });
  });
});

module.exports = router;

categories.js

var express = require("express");
var router = express.Router();
var mongo = require("mongodb");
var db = require("monk")("localhost/nodeblog");

router.get("/show/:category", function(req, res, next) {
  var posts = db.get("posts");

  posts.find({ category: req.params.category }, {}, function(err, posts) {
    res.render("index", {
      title: req.params.category,
      posts: posts
    });
  });
});

router.get("/add", function(req, res, next) {
  res.render("addcategory", {
    title: "Add Category"
  });
});

router.post("/add", function(req, res, next) {
  // Get Form Values
  var name = req.body.name;

  // Form Validation
  req.checkBody("name", "Name field is required").notEmpty();

  // Check Errors
  var errors = req.validationErrors();

  if (errors) {
    res.render("addpost", {
      errors: errors
    });
  } else {
    var categories = db.get("categories");
    categories.insert(
      {
        name: name
      },
      function(err, post) {
        if (err) {
          res.send(err);
        } else {
          req.flash("success", "Category Added");
          res.location("/");
          res.redirect("/");
        }
      }
    );
  }
});

module.exports = router;

show.pug

extends layout
block content
    .post
     h1=post.title
     p.meta Posted in 
      a.category-link(href='/categories/show/' + post.category) #{post.category} 
      | by #{post.author} on #{moment(post.date).format("MM-DD-YYYY")}
     img.main-image(src='/images/' + post.mainimage)
     !=post.body

Originally, I had

posts.findById(

but that did not work either.

Any help on this will be greatly appreciated. Thank you in advance.

This code here is causing the issue.

app.use(function(req, res, next) {
  var err = new Error("Not Found");
  err.status = 404;
  next(err);
});

Effectively this code is middleware that changes the status of every request to 404.

you should pass the id paramater as an objectId by converting it using the mongoDB module

var ObjectId = require("mongodb").ObjectId;

router.get("/show/:id", function (req, res, next) {
  var posts = db.get("posts");

  posts.findOne({ '_id': new ObjectId(req.params.id }, function (err, post) {
    res.render("show", {
      'post': post
    });
  });
});```

I would suggest you to use findById as you are finding by id and use promise. in your case it would be like:

posts.findById({ '_id': req.params.id })
.then(post => {
  res.render(post)
})
.catch(error => {
  console.log(error)
})

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM