A little background. I am sending a post with the username. About what he came to me is displayed in the log.
console.log(req.body.username); // 'username'
How do I use mongodb to find and render a user with a username from the post?
For example, the sample and render of all users looks like this, but I still do not understand how to get the one I need
exports.profile = function(req, res, next){
User.find(function(err,users){
if(err) return next(err);
res.render('users/profile',{ users:users });
});}
Try this
exports.profile = function(req, res, next){
User.find({username: req.body.username}function(err,users){
if(err) return next(err);
res.render('users/profile',{ users:users });
});}
and here you have some docs to read http://mongoosejs.com/docs/queries.html
Use findOne function to find.
User.findOne({username: req.body.username}.function(err,users){
if(err) return next(err);
res.render('users/profile',{ users:users });
});}
Related
i am getting started with node.js and now I got stuck.
var mysql = require('mysql');
var dbconfig = require('../config/database');
var connection = mysql.createConnection(dbconfig.connection);
connection.query('USE ' + dbconfig.database);
app.get('/createarticle', isLoggedIn, function(req, res){
res.render('createarticle.ejs', {
user:req.user
});
});
app.post('/createarticle' , (req, res ) => {
let sql = 'INSERT INTO news SET ?'
let post = {
// author: req.user.username,
content : req.body.content,
title: req.body.title
}
connection.query(sql, post, (err, res) => {
if(err) throw err;
console.log('success');
console.log(res);
});
});
If I use req.user.username I get this error message Cannot read property 'username' of undefined.
I also tried user.username and req.user.
In my main JS I have this function that shoud always give the user if logged in.
app.get('*', function(req, res, next) {
res.locals.user = req.user || null;
next();
});
In addition to this I want to include two redirects but I don't know where to put it.
successRedirect: '/',
failureRedirect: '/createarticle',
I appreciate every answer and pacience with me. :)
I can't comment so I have to post an answer:
What does your request object look like:
app.get('/createarticle', isLoggedIn, function(req, res){
console.log('request',req)
res.render('createarticle.ejs', {
user:req.user
});
});
If you're not populating the request object in your 'GET' from your front end,
you won't have the user you are asking for.
You may want to do some handling in the front to make sure that you only send populated request objects.
router.get('/deleteRecord/delete/:id', function(req, res){
db.collection('inventories').remove({_id: mongodb.ObjectID( req.params.id)}, (err, result) => {
if (err) return console.log(err)
console.log('Welcome to Delete Function');
res.redirect('deleteRecord');
});
});
handlebars: Delete
Gettting the ID back but record isn't being deleted
Try this
db.collection('inventories').find({_id: mongodb.ObjectID( req.params.id)}).remove()
When attempting to use req.params.id inside my delete (or update for that matter) route I am getting the above message. This has stumpted me for some time and I'm sure I'm making a mistake somewhere with my routes / objects.
Changing the app from res.render("/campgrounds/ + req.params.id); to -
res.render("/campgrounds"); solves the issue but doesn't reload the same page like i'm look to have it do. I can't wrap my head around why the app is returning undefined when accessing the campground route from req.params.id.
var express= require("express");
var router = express.Router();
var Comment = require("../models/comment");
var Campground = require("../models/campgrounds");
// COMMENTS EDIT ROUTE
router.get("/campgrounds/:id/comments/:comment_id/edit", function(req, res){
Comment.findById(req.params.comment_id, function(err, foundComment){
if(err){
console.log(err)
} else {
res.render("comments/edit", {campground_id: req.params.id, comment: foundComment})
}
})
})
// comment update
//campgrounds/:id/comments/:comment_id
router.put("/:comment_id", function(req, res){
Comment.findByIdAndUpdate(req.params.comment_id, req.body.comment, function(err, updatedComment){
if(err){
console.log(err)
} else {
// KNOWN BUG - /campgrounds/ + req.params.id will return cast to boject failed for value undefined at path _id. having the app redirect to all campgrounds page as a work around
res.redirect("/campgrounds");
}
})
})
// DELETE ROUTER
router.delete("/:comment_id", function(req, res){
Comment.findByIdAndRemove(req.params.comment_id, function(err){
if(err){
res.redirect("back");
} else {
res.redirect("/campgrounds/" + req.params.id);
}
})
})
function isLoggedIn(req, res, next){
if(req.isAuthenticated()){
return next();
} else {
res.redirect("/login");
}
}
module.exports = router;
I've ran into the same issue, and it was due to route order. I moved the show route below the index route cuz "it flows better", but that broke the code, and confused it since I think route order matters. make sure your route make sense from the applications point of view if you reordered them
Make sure you have input field name "id" in comment form (or "id" in ajax request).
router.put("/:comment_id", function(req, res){
const id = req.params.id;
console.log(id);
Comment.findByIdAndUpdate(req.params.comment_id, req.body.comment, function(err, updatedComment){
if(err){
console.log(err)
} else {
res.redirect("/campgrounds/" + id);
}
})
})
I think your problem is you are not sending the comment_id from html to controller try printing the req.params.comnent_id
then try this
var express= require("express");
var router = express.Router();
var Comment = require("../models/comment");
var Campground = require("../models/campgrounds");
// COMMENTS EDIT ROUTE
router.get("/campgrounds/:id/comments/:comment_id/edit", function(req, res){
console.log("params.comment_id",params.comment_id);
if(req.params.comment_id){
Comment.findById(req.params.comment_id, function(err, foundComment){
if(err){
console.log(err)
} else {
res.render("comments/edit", {campground_id: req.params.id, comment: foundComment})
}
}else {
res.render("comments/edit", {campground_id: req.params.id, comment: foundComment})
}
})
})
Ok guys, I recently encountered the same problem. I tried finding solutions all over the internet but failed to get any useful answers.
Then I tried looking hard into the "CastError" and found that the ID I am getting from 'req.params.id' had an extra white space in front of it.
For example: instead of '5bed4f6276c4920db404eb25', I got ' 5bed4f6276c4920db404eb25' as the ID. I don't know (yet) why I get the id with that extra white space but I figured that white space must be the issue.
So I stripped the ID for white space with javascript replace function as follows:
var curid = req.params.id;
curid = curid.replace(/\s/g,'');
and it worked!
So instead of
Campground.findByIdAndUpdate(req.params.id, req.body.campground, function(err, updatedCamp){..}
now use:
Campground.findByIdAndUpdate(curid, req.body.campground, function(err, updatedCamp){..}
So,you have to replace all
req.params.id
in your code block with
curid
And you are good to go!
Here is the whole code block for your reference:
router.put("/:id", function(req, res){
var curid = req.params.id;
curid = curid.replace(/\s/g,'');
Campground.findByIdAndUpdate(curid, req.body.campground, function(err, updatedCamp){
if(err){
console.log(err);
res.redirect("/campgrounds");
} else{
//redirect somewhere (show page)
res.redirect("/campgrounds/" + curid);
}
});
The best solution to this problem is reformat the _id by cleaning the blank space it added (in my case coming from a form in my template "x.ejs")
const to_remove = req.body.checkbox;//id from template is wrong
const listname = req.body.check_list_name;
let **to_rem_cured** = to_remove.replace(/\s/g,'');
List.findOneAndUpdate({name:listname},{'$pull':{list:{_id: **to_rem_cured** }}},function(err,doc){
if(!err){
console.log(doc);
res.redirect("/"+listname);
}
else{
console.log(err);
}
});
I just started a project using Express and I have no real knowledge in node.js, and even in Javascript in general. I was wondering what was the proper way of throwing and catching errors so that they display correctly, and also so that I don't duplicate too much code. I thought this bit of code in app.js:
// 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: {}
});
});
acted like a big catch that would intercept all the errors I would throw in my controllers. But I don't really know how to make it work. For example, let's take this bit of code in users.js:
/* GET users listing. */
router.get('/', function(req, res, next) {
connection.query('SELECT id, name FROM user', function(err, rows, fields) {
if (err) throw err;
res.render('users', {
title: 'Users',
userList: rows
});
});
});
How do I send something like a 204 code (No Content)
How do I report an error with the database
Any help/hint would be appreciated, I'll keep looking on forums and stuff in the meantime.
Express uses a series of middleware to handle the request. If the route matches and defined route it will handle it. Otherwise, you can put '/404' route at last after importing all the routes. It will automatically reach there when no route is found. Else if you don't want to send a response you can use next() so that it moves to next middleware and ultimately to '/404' middleware.
/* GET users listing. */
router.get('/', function(req, res, next) {
connection.query('SELECT id, name FROM user', function(err, rows, fields) {
if (err) {
return res.status(502).json({message:'db error'});
};
res.render('users', {
title: 'Users',
userList: rows
});
});
});
Thank you all for your answers. What I was looking for (and found) was the next(error) function to pass control to the error handler located in app.js (Cf. http://expressjs.com/en/guide/routing.html for more details).
You can give a relevant message with statusCode like this
/* GET users listing. */
router.get('/', function(req, res, next) {
connection.query('SELECT id, name FROM user', function(err, rows, fields) {
if (err){
res.status(500).send("Something is not right");
};
//if you get rows of array type, then you can do this for empty records
else if(rows.length===0){
res.status(204).send('No records found!')
}else{
res.render('users', {
title: 'Users',
userList: rows
});
}
});
});
In Express, each route handler is passed a 'res' parameter, that is used to provide the response to the client. Sample usage of creating a response with a specific code, code error and empty body
router.get('/', function(req, res, next) {
res.status(401, "Authentication mismatch").json({});
});
Instead of json() you can also use send() to send a plain text back.
Using ReactJS, Redux, Webpack, Node.js and Express with MongoDB, I am following the tutorial https://github.com/vasansr/mern-es6 and trying to integrate it into my project. First, I am trying to make a POST request to the server I created. And it gets a response with a success and no error is logged. Yet inside the server POST API, it does not log console.log('Req body', req.body);, and in terminal I checked to see if the database has been created with mongo -> show dbs but it is empty.
Could it be that something is intercepting the request from the server? What could be the issue?
This...
app.use('/', function (req, res) {
res.sendFile(path.resolve('client/index.html'));
});
comes before:
app.post('/api/users/', function(req, res) {
//...
});
Since it's app.use the POST /api/users will still hit that middleware, and res.sendFile ends the request/response. You'll probably see that your post is getting back the client HTML.
Try moving your client HTML endpoint to the end of your middleware, just before the error handlers if you have them. That way, it'll only get used if none of your API endpoints match. Or if you want just GET / to return the HTML, change use to get:
app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
app.use(webpackHotMiddleware(compiler));
app.use(express.static('dist')); //where bundle.js is
app.use(bodyParser.json());
app.post('/api/users/', function(req, res) {
console.log('Req body', req.body);
var newUser = req.body;
db.collection('users').insertOne(newUser, function(err, result) {
if(err) console.log(err);
var newId = result.insertedId;
db.collection('users').find({_id: newId}).next(function(err, doc) {
if(err) console.log(err);
res.json(doc);
});
});
});
app.get('/', function (req, res) {
res.sendFile(path.resolve('client/index.html'));
});
app.post('/api/users/', function(req, res) {
console.log('Req body', req.body);
var newUser = req.body;
db.collection('users').insertOne(newUser, function(err, result) {
if(err) console.log(err);
var newId = result.insertedId;
db.collection('users').find({_id: newId}).next(function(err, doc) {
if(err) console.log(err);
res.json(doc);
});
});
});
I have a small comments about this code, for if(err) console.log(err); i think you should change to if(err) return console.log(err);.
For error case, i think you need return, otherwise the below part will be excuted, and there will report some error.