I'm trying to use mongoose/express to add form data to a db. The collection is created within the database and although there are no errors when submitting, and my console.log confirms the data is there along with a generated ID i still don't have any entries within the database, can you see what I'm missing? Any help would be really appreciated.
**CONFIG**
const port = process.env.PORT || 3000,
bodyparser = require("body-parser"),
mongoose = require("mongoose"),
express = require("express"),
app = express();
app.set("view engine", "ejs");
app.use(
bodyparser.urlencoded({
extended: true
})
);
app.use(
require("express-session")({
secret: "Mama Mia Thats a Spicy Meatball!",
resave: false,
saveUninitialized: false
})
);
app.use(express.static(__dirname + "/styles/"));
app.use(express.static(__dirname + "/Media/"));
app.use(express.static(__dirname + "/JS/"));
mongoose.connect("mongodb://localhost/lashB", {
useNewUrlParser: true
});
const mongCon = mongoose.connection;
mongCon.on("connected", function () {
console.log(`beep boop
database mainframe syncroniiiiiiized`);
});
mongCon.on("disconnected", function () {
console.log(`You're off the database now...Daniel San.`);
});
mongCon.on('error', function () {
console.log(error, `We've got company...there's an error!!!`);
});
**SCHEMA**
var customerSchema = new mongoose.Schema({
firstName: String,
lastName: String,
mobile: String,
email: String,
treatment: String,
time: String,
date: Date
});
var Customer = mongoose.model("Customer", customerSchema, "Customer");
**ROUTES**
app.get("/", function (req, res) {
res.render("main");
});
app.get("/appointment", function (req, res) {
res.render("appointment");
});
app.get("/appointmentConfirmation", function (req, res) {
res.render("appConfirmation");
});
app.get("/blogHome", function (req, res) {
res.render("blogHome");
});
app.post('/appointment', function (req, res) {
var firstName = req.body.firstName,
lastName = req.body.lastName,
mobile = req.body.mobile,
email = req.body.email,
treatment = req.body.treatment,
time = req.body.time,
date = req.body.date;
var deetz = {
date: date,
time: time,
treatment: treatment,
email: email,
mobile: mobile,
firstName: firstName,
lastName: lastName
}
Customer.create(deetz, function (err, info) {
if (err) {
console.log(err, `something went wrong`);
} else {
console.log(info);
console.log('newly created file for a customer');
}
});
res.render('appConfirmation', {
firstName: firstName
}
);
});
app.listen(port, function () {
console.log(`You rockin' now on port ${port}`);
});
Fixed it. The mistake was that i was entering 'use' nameofcollection, but 'use' is for the db and not collections. So show dbs > use nameofdb > db.nameofcollection.find() worked just fine.
Related
I created some sample code to demonstrate my issue on a smaller scale. From my understanding, a getter function will not affect anything on my database, but when I want to make a get request to view items on my database, it will change the value to whatever is returned only when the data is displayed. However, when I make my get request to view items on my database, the item I am shown is exactly how it was saved. I'm not sure if I'm misunderstanding what a getter function is, or if my syntax is just incorrect somewhere.
Here is my main server:
const express = require('express')
const mongoose = require('mongoose')
// Linking my model
const User = require('./User')
// Initializing express
const app = express()
const PORT = 9999
app.use(express.json())
// Connecting to mongodb
const connectDB = async () => {
try {
await mongoose.connect('mongodb://localhost/testdatabase', {
useUnifiedTopology: true,
useNewUrlParser: true
})
console.log('Connected')
} catch (error) {
console.log('Failed to connect')
}
}
connectDB()
// Creates a new user
app.post('/user/create', async (req, res) => {
await User.create({
name: 'John Cena',
password: 'somepassword'
})
return res.json('User created')
})
// Allows me to view all my users
app.get('/user/view', async (req, res) => {
const findUser = await User.find()
return res.json(findUser)
})
// Running my server
app.listen(PORT, () => {
console.log(`Listening on localhost:${PORT}...`)
})
Here is my model:
const mongoose = require('mongoose')
// My setter - initialPassword is 'somepassword'
// This seems to work properly, in my database the password is changed to 'everyone has the same password here'
const autoChangePassword = (initialPassword) => {
console.log(initialPassword)
return 'everyone has the same password here'
}
// My getter - changedPassword should be 'everyone has the same password here' I think
// The console.log doesn't even run
const passwordReveal = (changedPassword) => {
console.log(changedPassword)
return 'fakehash1234'
}
// Creating my model
const UserSchema = mongoose.Schema({
name: {
type: String
},
password: {
type: String,
set: autoChangePassword,
get: passwordReveal
}
})
// Exporting my model
const model = mongoose.model('user', UserSchema)
module.exports = model
Not sure if it would help anyone since I found my answer on another StackOverflow post, but the issue was I had to set getters to true when converting back to JSON:
// Creating my model
const UserSchema = mongoose.Schema({
name: {
type: String
},
password: {
type: String,
set: autoChangePassword,
get: passwordReveal
}
}, {
toJSON: { getters: true }
})
Any similar problems can be solved by adding some combination of the following:
{
toJSON: {
getters: true,
setters: true
},
toObject: {
getters: true,
setters: true
}
}
I am trying to have a user log in by their email and password. MongoDb docs shows hashing the password with bcrypt in the user model. It also provides a nice way to validate the password in the model as well. My problem is how to I use that validation from the "controller"? I am very aware "if (req.body.password === user.password)" will not work because one is hashed and the other is not.
I have been searching for answers for hours and can't seem to find that connection on how I use that "UserSchema.methods.comparePassword" method in my post request to log in. This isn't completely a real log in, just trying to get the password to validate and send back a key once logged in. Here are the docs: https://www.mongodb.com/blog/post/password-authentication-with-mongoose-part-1
// This is my UserModel
let mongoose = require('mongoose'),
Schema = mongoose.Schema,
bcrypt = require('bcrypt'),
SALT_WORK_FACTOR = 10
var hat = require('hat');
let UserSchema = new Schema({
email: {
type: String,
required: true,
index: {
unique: true
}
},
password: {
type: String,
require: true
},
api_key: {
type: String
}
});
UserSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
user.api_key = hat();
next();
});
});
});
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
module.exports = mongoose.model('user', UserSchema);
// This is the sessions.js
let UserModel = require('../../../models/user.model');
var express = require('express');
var router = express.Router();
router.post('/', (req, res, next) => {
UserModel.findOne(
{
$or: [
{ email : req.body.email }
]
}
)
.then(user => {
if (req.body.password === user.password) {
res.setHeader("Content-Type", "application/json");
res.status(200).send(JSON.stringify({
"api_key": `${user.api_key}`
}));
} else {
res.status(404).send("Incorrect email or password")
}
})
.catch(error => {
res.setHeader("Content-Type", "application/json");
res.status(500).send({error})
})
})
module.exports = router
If I just find user by email, everything works fine. Just need to figure out how to use the compare password method in the user model. Thanks!
Maybe have something like this in your model:
User = require('./user-model');
.......
User.findOne({ username: 'jmar777' }, function(err, user) {
if (err) throw err;
user.comparePassword('Password123', function(err, isMatch) {
if (err) throw err;
console.log('Password123:', isMatch); // -> Password123: true
});
........
Other resources:
http://devsmash.com/blog/password-authentication-with-mongoose-and-bcrypt
https://www.abeautifulsite.net/hashing-passwords-with-nodejs-and-bcrypt
https://medium.com/#mridu.sh92/a-quick-guide-for-authentication-using-bcrypt-on-express-nodejs-1d8791bb418f
Hope it helps!
I'm trying to put up a simple form handling project. The post method is not getting called. There is no output from the post method. I do not understand why this is happening. What is the issue here?
This is the code I'm using.
var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();
var app = express();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String,
});
var Person = mongoose.model('Person', personSchema);
app.get('/', function(req, res) {
res.render('person');
});
app.set('view engine', 'pug');
app.set('views', './views');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(upload.array());
app.use(express.static('public'));
app.post('/', function(req, res) {
var personInfo = req.body; //Get the parsed information
if (!personInfo.name || !personInfo.age || !personInfo.nationality) {
res.render('show_message', {
message: 'Sorry, you provided worng info',
type: 'error',
});
} else {
var newPerson = new Person({
name: personInfo.name,
age: personInfo.age,
nationality: personInfo.nationality,
});
newPerson.save(function(err, Person) {
if (err) res.render('show_message', { message: 'Database error', type: 'error' });
else
res.render('show_message', {
message: 'New person added',
type: 'success',
person: personInfo,
});
});
}
});
app.listen(3000);
I would like to know how to fix this issue.
I tried putting a console.log() output to log if the post method is being called. But there was no output from it either.
I looked at this popular question, but it didn't seem to fix my issue, so I'm going to post this.
I currently have an express.js server file using mongoose, that keeps returning an empty array. I have no idea if it might by an async issue, and I don't know what I can use to indicate that I'm connected to my database.
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const PORT = process.env.PORT || 8080;
//Mongoose stuff
mongoose.connect('mongodb+srv://excelsiorAdmin:Mysecretpassword#excelsiorcluster-zakfd.mongodb.net/test?retryWrites=true', { useNewUrlParser: true, dbName: 'excelsiorDB'});
const dbConnection = mongoose.connection;
dbConnection.on('error', console.error.bind(console, 'connection error:'));
dbConnection.once('open', function() {
console.log('connected to the database');
let charSchema = new mongoose.Schema({
imageURL: String,
company: String,
name: String,
civName: String,
alignment: String,
firstDebut: String,
abilities: Array,
teams: Array,
desc: String
});
let Char = mongoose.model('Char', charSchema, 'chars');
//root
app.get('/', (req, res, next) => res.send('Welcome to the API!'));
//get all characters
app.get('/chars', (req, res, next) => {
console.log('getting all characters');
Char.find(function (err, chars) {
if (err) {
res.status(404).send(err);
console.log('there was an error');
};
console.log(chars);
res.send(chars);
});
});
//get heroes
app.get('/chars/heroes', (req, res, next) => {
Char.find({alignment: "Hero"}, function (err, chars) {
if (err) {
res.status(404).send(err);
};
res.send(chars);
});
});
});
app.listen(PORT, () => console.log(`This API is listening on port ${PORT}!`));
The mongoose.model will set the collection it's looking for equal to the lowercase, pluralized form of the name of the model.
let Char = mongoose.model('Char', charSchema);
This will look for the "chars" collection. However, if the database you're connecting to doesn't have a collection with the same name as the mongoose default, it will return results from a collection that doesn't exist. To make sure it hits the right collection if they don't match, you'll have to manually enter the collection's name as a third parameter:
let Char = mongoose.model('Char', charSchema, "excelsiorCollection");
I have a problem. I'm trying to save answers from a survey. My problem is that I'm sending these answers through axios and they are showing in the console.log from the server, which means that my data is reaching the server safely. But data is not being saved. Also no error is shown.
Server.js
router.route('/answers')
//post answers to database
.put(function(req, res){
var survey = new Survey();
survey.name = req.body.name;
survey.email = req.body.email;
survey.q_id = req.body.q_id;
survey.q_text = req.body.q_text;
survey.answer = req.body.answer;
console.log(Survey.collection)
survey.save(function(err){
if(err){
console.log(err)
return ;
}
res.send(survey);
});
})
Survey.js (Model)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;
var question = new Schema({
q_text:String,
order: Number,
options:[{
type: {type: String},
value: {type: String}
}]
});
module.exports = mongoose.model('Question',question);
Code that is posting the data
const url = 'http://localhost:3100/api/answers';
axios.put(url, survey)
.then(res => {
console.log('Successfully posted');
console.log(res);
setSubmitting(false);
setStatus({submitted: true});
})
.catch(err => {
console.log(err);
})
Try this :
survey.save(function(err, savedSurvey){
if(err){
console.log(err)
return ;
}
res.send(savedSurvey);
});