When I try to run my code in the browser using: http://localhost:3000/contact-list I keep getting a TypeError: User.find is not a function.
I'm working on a project that uses Ejs, MongoDB and Node.
This is the code I have written in my user-contact.js file inside my controllers folder:
let express = require('express');
let router = express.Router();
let mongoose = require('mongoose');
// Create a reference to the model
let User = require('../models/user');
module.exports.displayUserList = (req, res, next) => {
User.find((err, userList) => {
if(err) {
return console.error(err);
} else {
res.render('user/list', {title: 'Business Contacts', UserList: userList, displayName: req.user ? req.user.displayName : ''});
}
}) .sort({name: 1});
};
module.exports.displayAddPage = (req, res, next) => {
res.render('user/add', {title: 'Add New Contact', displayName: req.user ? req.user.displayName : ''});
};
module.exports.processAddPage = (req, res, next) => {
let newUser = User({
"name": req.body.name,
"number": req.body.number,
"email": req.body.email
});
User.create(newUser, (err, User) => {
if(err) {
console.log(err);
res.end(err);
} else {
// Refresh the Contact List
res.redirect('/contact-list');
}
});
};
module.exports.displayEditPage = (req, res, next) => {
let id = req.params.id;
User.findById(id, (err, userToEdit) => {
if(err){
console.log(err);
res.end(err);
} else {
// Show the Edit view
res.render('user/edit', {title: 'Update Contacts', user: userToEdit, displayName: req.user ? req.user.displayName : ''});
}
});
};
module.exports.processEditPage = (req, res, next) => {
let id = req.params.id;
let updatedUser = User({
"_id": id,
"name": req.body.name,
"number": req.body.number,
"email": req.body.email
});
User.updateOne({_id: id}, updatedUser, (err) => {
if(err) {
console.log(err);
res.end(err);
} else {
// Refresh the Contact List
res.redirect('/contact-list');
}
});
};
module.exports.performDelete = (req, res, next) => {
let id = req.params.id;
User.remove({_id: id}, (err) => {
if(err) {
console.log(err);
res.end(err);
} else {
// Refresh the Contact List
res.redirect('/contact-list');
}
});
};
The output should show the contact-list information. Instead, I'm getting an error that User.find is not a function, but I clearly have it inside a function.
I would really appreciate if someone could help me out.
I want to select all users except current longlined user using email address, I don't want to show his details so how it is possible in node js?
router.get('/', function(req, res, next) {
const jsonObj = jsonToken.verify(req.cookies.email, process.env.privateKey);
const userEmail = jsonObj.userEmail
console.log(userEmail)
userModel.find().exec((err, data)=> {
if (err) throw err;
res.status(200).json(data);
res.render('index', { title: 'Secret Santa', users: data });
})
You can add not equal to condition in your find query,
userModel.find({ email: { $ne: userEmail } }).exec((err, data)=> {
if (err) throw err;
res.status(200).json(data);
res.render('index', { title: 'Secret Santa', users: data });
})
Hello everyone i am in a problem, may be you can help me.
So basically i have created two collection in mongoose, one for user details when they sign Up or login and other for Recipe they post.
I also want to save the each recipe a user post in the user collection (like populate property of mongoose). like if user1 post a recipe1 then it should save in the recipe collection and also in the user data who posted this.
I tried to use Populate method for this as shown in the code below but when ever i post some recipe it stored in recipe collection only and the "posts" key in the users collection is always empty. I want to save the recipe in the "posts" key of the users collection also.
Please Guide me how to do this.
require('dotenv').config()
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const requestObj = require("request");
const https = require("https");
const multer = require("multer");
const path = require("path");
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
const findOrCreate = require('mongoose-findorcreate');
const app = express();
const GoogleStrategy = require('passport-google-oauth20').Strategy;
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
app.use(session({
secret: "This is my secret",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
// Mongoose connection
mongoose.connect("mongodb://localhost:27017/recipeUsers", {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.set('useCreateIndex', true);
//mongoose schema
const userSchema = new mongoose.Schema({
username: String,
password: String,
googleId: String,
name: String,
posts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Recipe'
}]
});
const recipeSchema = new mongoose.Schema({
genre: String,
name: String,
description: String,
ingredients: [{
type: String
}],
method: [{
type: String
}],
imageName: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
userSchema.plugin(passportLocalMongoose);
userSchema.plugin(findOrCreate);
// model
const Recipe = mongoose.model("Recipe", recipeSchema);
const User = mongoose.model("User", userSchema);
module.exports = {
User,
Recipe,
}
passport.use(User.createStrategy());
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use(new GoogleStrategy({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: "http://localhost:5000/auth/google/index",
userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo"
},
function(accessToken, refreshToken, profile, cb) {
// console.log(profile);
User.findOrCreate({
googleId: profile.id,
name: profile.displayName
}, function(err, user) {
return cb(err, user);
});
}
));
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "public/img/uploads")
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
var upload = multer({
storage: storage,
limits: {
fileSize: 5 * 1024 * 1024
}
});
app.use((req, res, next) => {
res.locals.isAuthenticated = req.isAuthenticated();
if (req.isAuthenticated()) {
currentUser = req.user.name;
}
next();
});
app.get("/", function(req, res) {
res.render("index");
});
app.get("/index", (req, res) => {
res.render('index');
});
app.get("/about", function(req, res) {
res.render("about");
});
app.route("/search")
.get(function(req, res) {
res.render("search");
})
.post(function(req, res) {
const searchRecipe = req.body.recipeName;
Recipe.findOne({
name: searchRecipe
}, (err, foundRecipe) => {
if (err) {
res.send(err);
} else {
if (foundRecipe) {
res.render("recipe", {
dishName: foundRecipe.name,
descrip: foundRecipe.description,
genre: foundRecipe.genre,
ingredients: foundRecipe.ingredients,
steps: foundRecipe.method,
author: foundRecipe.author,
dishImage: foundRecipe.imageName
});
} else {
res.redirect("/Failure");
}
}
});
});
app.get("/Failure", function(req, res) {
res.render("Failure");
});
app.route("/post")
.get(function(req, res) {
if (req.isAuthenticated()) {
res.render("post", {
message: ""
});
} else {
res.redirect("/login");
}
})
.post(upload.single('dishImage'), function(req, res, next) {
const dishType = req.body.recipeGenre;
const description = req.body.description;
const dishName = req.body.dishName;
const ingredient = req.body.ingredients;
const step = req.body.steps;
// const authorName = req.body.author;
// const url = "https://polar-oasis-10822.herokuapp.com/recipes";
const file = req.file;
if (!file) {
const error = new Error("Please upload a image");
error.httpStatusCode = 400;
return next(error);
}
// console.log(req.user);
const dish = new Recipe({
genre: dishType,
name: dishName,
description: description,
ingredients: ingredient,
method: step,
imageName: file.filename,
});
dish.save((err) => {
if (err) {
res.send(err);
} else {
User.findOne({
_id: req.user._id
})
.populate('posts').exec((err, posts) => {
console.log("Populated User " + posts);
})
res.render("post", {
message: "Your Recipe is successfully posted."
});
}
});
});
app.get("/menu", function(req, res) {
res.render("menu");
});
app.get('/auth/google',
passport.authenticate('google', {
scope: ["profile"]
})
);
app.get('/auth/google/index', passport.authenticate('google', {
failureRedirect: '/login'
}), function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
app.get("/logout", (req, res) => {
req.logout();
res.redirect('/');
});
app.route("/signup")
.get((req, res) => {
res.render("signup");
})
.post((req, res) => {
User.register({
username: req.body.username,
name: req.body.name,
}, req.body.password, (err, user) => {
if (err) {
console.log(err);
res.redirect("/signup");
} else {
passport.authenticate("local")(req, res, () => {
res.redirect('/');
});
}
});
})
app.route("/login")
.get((req, res) => {
res.render("login");
})
.post((req, res) => {
const user = new User({
username: req.body.username,
password: req.body.password
});
req.login(user, (err) => {
if (err) {
console.log(err);
} else {
passport.authenticate("local")(req, res, () => {
res.redirect("/");
});
}
});
})
app.listen(process.env.PORT || 5000, function() {
console.log("server is running on port 5000");
});
I believe your problem is here:
dish.save((err) => {
if (err) {
res.send(err);
} else {
User.findOne({
_id: req.user._id
})
.populate('posts').exec((err, posts) => {
console.log("Populated User " + posts);
})
res.render("post", {
message: "Your Recipe is successfully posted."
});
}
});
});
You are using populate as a function that changes the dataset elements, but it is just a trick for printing results from different collection, in the roots, they are different; if you want them to be in the same document, you must use subdocuments. populate does not change document paths.
Assuming I have not typed anything wrong, that you must correct yourself or let me know, this should solve your problem; just use populate to print the documents our as one, not to save.
app
.route("/post")
.get(function(req, res) {
if (req.isAuthenticated()) {
res.render("post", {
message: ""
});
} else {
res.redirect("/login");
}
})
.post(upload.single("dishImage"), function(req, res, next) {
const dishType = req.body.recipeGenre;
const description = req.body.description;
const dishName = req.body.dishName;
const ingredient = req.body.ingredients;
const step = req.body.steps;
const username = req.body.author; //make sure this information is passed to req.body
// const url = "https://polar-oasis-10822.herokuapp.com/recipes";
const file = req.file;
if (!file) {
const error = new Error("Please upload a image");
error.httpStatusCode = 400;
return next(error);
}
// console.log(req.user);
const dish = new Recipe({
genre: dishType,
name: dishName,
description: description,
ingredients: ingredient,
method: step,
imageName: file.filename
});
dish.save(err => {
if (err) {
res.send(err);
} else {
User.findOne({
_id: req.user._id
}).then(user => {//I have changed just here! I have eliminated the populate call
user.posts.push(dish._id);
user.save().then(() => {
console.log("okay");
});
});
res.render("post", {
message: "Your Recipe is successfully posted."
});
}
});
});
Since your code is big, I may have missed something, please, let me know if I have misunderstood what you wanted.
References
https://mongoosejs.com/docs/populate.html#refs-to-children
Im using POSTMAN to delete contact using id and it returns
{
"n": 0,
"ok": 1
}
This is my delete code so far
router.delete('/contact/:id', (req, res, next) => {
contact.remove({ _id: new objectId(req.params._id) }, function(err, result) {
if (err) {
res.json(err);
} else {
res.json(result);
}
});
});
You need to pass the _id value as an ObjectID, not a string:
var mongodb = require('mongodb');
router.delete('/contact/:id', (req, res, next) => {
contact.deleteOne({ _id: new mongodb.ObjectID(req.params._id) }, function(err, result) {
if (err) {
res.json(err);
} else {
res.json(result);
}
});
});
id !== _id
change :id in your route to :_id and you should be fine.
I cannot remove an element inside of an array that is a property of a MongoDB Model.
Please remember this is a NodeJS module mongooseJS and not the real MongoDB so functionalities are not the same..
GOAL: Delete an object from the statusLiked array. | I have also confirmed that the value of status.id is correct.
Model:
Const userSchema = new mongoose.Schema({
myStatus: Array,
statusLiked: Array,
)};
Delete:
1. Deletes the status(works). 2. Delete the status from User.statusLiked(no work).
exports.deleteStatus = (req, res, next) => {
var CurrentPost = req.body.statusid; // sends in the status.id
Status.remove({ _id: CurrentPost }, (err) => {
if (err) { return next(err); }
// vvvv this vvv
User.update( {id: req.user.id}, { $pullAll: {_id: CurrentPost }, function(err) { console.log('error: '+err) } });
req.flash('success', { msg: 'Status deleted.' });
res.redirect('/');
});
};
What happens: The specific status(object) is deleted from the database. But the status still remains in the User.statusLiked array.
What I want to happen: Status to be deleted from the User.statusLiked array and the status to be deleted from the database. Then, reload the page and display a notification.
I got it to work somehow. Working code:
exports.deleteStatus = (req, res, next) => {
var CurrUser = req.body.userid;
var CurrentPost = req.body.post;
Status.remove({ _id: CurrentPost }, (err) => {
if (err) { return next(err); }
console.log('meeee'+CurrentPost+'user: ' +CurrUser);
req.flash('success', { msg: 'Status deleted.' });
res.redirect('/');
});
User.update(
{ _id: new ObjectId(CurrUser)},
{ $pull: { myStatus : { _id : new ObjectId(CurrentPost) } } },
{ safe: true },
function (err, obj) {
console.log(err || obj);
});
};