How to stop node inserting data into mongodb when I reload page - node.js

I have a page with a form that allows you to insert information into a collection called "Farm". The function works, but if I ever reload the page the information gets submitted into the again. I created a filter function that avoids inserting the data if the req.body has a similar name and species property. But, I feel that there is a better way to go about doing this. Here is the code that creates the information and pushes the data into mongodb
var mongoose = require('mongoose');
var f = mongoose.model('Farm');
module.exports create = function(req,res){
var obj = req.body;
console.log(obj)
f.find({}, function(err,docs){
var same = docs.some(function(element,index){
return (element.name === obj.name && element.species === obj.species);
})
if(same === true){
console.log('That name is already in the database');
res.render('add',{msg:"Animal is already in the database"});
}else{
f.create({
name: obj.name,
species: obj.species.toLowerCase(),
sex:obj.sex,
weight: obj.weight,
age: obj.age,
}, function(err,info){
if (err){
throw err;
}
var message = 'Congratulations you have successfully added a '+info.species;
res.render('add',{msg:message})
})
}
})
}

Typically the solution to this problem is to redirect the user to another page after inserting successfully (but not if there were errors, so the form can be edited and resubmitted).
res.redirect('/success')

Related

Node JS mongoose insert data at the beginning

I'm experimenting with mongodb using mongoose in NodeJS.
I have a simple web where a user can create a post.
On creation this post is saved to mongodb.
On the web, i have a scroll event listener which checks if the user is on the bottom of the page or not. If he is on the bottom, it will do a fetch to the backend to get more posts.
I want these to be retrived from the db from newest to oldest, but the model.save() method of mongoose always inserts a new model at the end of the collection.
So when a new post created the backend does this right now:
const post = new Post({
text: req.body.text,
author: {
userid: user._id,
name: user.username,
picPath: user.picPath
},
images: images
});
post.save(function (err) {
let status = true;
let message = "Post mentve."
if (err) { status = false; message = err; console.log(err) }
return res.send({ status: status, msg: message });
})
This way, a new post pushed to the collection. And not unshifted.
When the client wants new posts the backend does this:
app.get('/dynamicPostLoad/:offset/:limit', async (req, res) => {
let offset = req.params.offset;
let limit = req.params.limit;
let response = {
status: true,
posts : [],
message: "Fetched"
};
await Post.find({}).skip(offset).limit(limit).then(products => {
response.posts = products;
}).catch((err)=> {
response.status = false;
response.message = err;
});
return res.send(response);
});
So the mongoose will fetch from oldest to newst since all the new is inserted at the end of the collection.
That way, the user will see the oldest post first and as he scrolls, sees the oldest and oldest posts.
I was thinking on three ways.
Either the Post.find({}) method should crawl the documents from the end of the collection or the Post.save() method should unshift the document instead of push or i could find all the posts in the collection and reverse them. ( the last one would be painfully slow )
EDIT: Every post contains a creation date, so it could be sorted.
How can i achive this?
I solved with sort. ( still don't understand why i can't insert a document to the beginning of a collection )
Here is my solution:
app.get('/dynamicPostLoad/:offset/:limit', async (req, res) => {
let offset = req.params.offset;
let limit = req.params.limit;
let response = {
status: true,
posts : [],
message: "Fetched"
};
// Sort every find by created date before limiting.
await Post.find({}).sort({created: -1}).skip(offset).limit(limit).then(products => {
response.posts = products;
}).catch((err)=> {
response.status = false;
response.message = err;
});
return res.send(response);
});

How to save schema data to another collection from route function

Hello I have less idea in express route as I am new in backend with mongodb.
In the route below I am verifying email by resetting a schema value to true. Now I want to copy the new schema details to another existing collection. How can I do that ?
router.get('/:adminId/verifyAdmin',function(req,res){
console.log('request recieved');
Admin.findOne( {_id: req.params.adminId })
.exec()
.then(admin => {
const Thing = mongoose.model(admin.companyName);
const emailTokenn = req.query.id;
//console.log(emailTokenn);
Thing.updateOne( { emailResetTokenn: emailTokenn },{ $set: { verified: true }},(err) =>{
if(!err){
return res.redirect('https://localhost:3000/fw18/index.html');
}
else{
throw err;
}
});
});
});
Here I want to pass/copy/save Thingcollection details to existing collection name users in my db.
EDIT:- Tried this but getting error export :- const User = mongoose.model('User');
Thing.updateOne( { emailResetTokenn: emailTokenn },{ $set: { verified: true }},(err) =>{
if(!err){
//add Thing Schema to Users collection
Thing = mongoose.model(admin);
var copy = mongoose.model('admin', admin,'User');
admin.save(function(err){});
return res.redirect('https://s3.ap-south-1.amazonaws.com/fw18/index.html');
}
Error:-
MissingSchemaError: Schema hasn't been registered for model correct me .
Http is a stateless protocol. To maintain state of the application you can use
1) session
2) cookies and
3) query string.
On your case, you can handle using session.
Store information to the session and get stored information from different routes.

Mongodb schema emptied after seconds

When i am making a request to save a new object to my mongodb, it gets saved, and after seconds everything in that schema disappears.
In the screenshot below you can see this happening, where with the first command i check that the schema is empty, then i make a request to save a new object which is done successfully, and after a few seconds you can see that the object has disappeared.
The express endpoint looks like so:
router.post('/bookdate',passport.authenticate('jwt', {session:false}), (req, res) => {
const userId = req.user._id
const appartmentNumber = req.user.apartmentNumber;
const requestedDate = req.body.requestedDate;
const bookingZone = req.body.bookingZone;
const newBooking = new Booking({
'apartmentNumber': appartmentNumber,
'dateOfBooking': requestedDate,
'bookingZone': bookingZone
});
if (req.user.hasTimeBooked) {
res.json({booked: false, msg: 'There is already a booking for this user.'})
} else {
if (typeof newBooking.requestedDate !== undefined && typeof newBooking.bookingZone !== undefined) {
Booking.addBooking(newBooking, (err, result)=>{
if(err){
res.json({booked: false, msg: err})
} else {
res.json({booked: true, msg: result})
}
})
} else {
res.json({booked: false, msg: 'Undefined parameters Date or Zone'})
}
}
});
and the mongoose schema looks like so
const mongoose = require('mongoose');
const config = require('../config/database');
const BookingSchema = mongoose.Schema({
apartmentNumber:{
type: Number,
unique: true
},
dateOfBooking:{
type: Date
},
bookingZone:{
type: String
}
});
const Booking = module.exports = mongoose.model('bookings',BookingSchema, 'bookings');
module.exports.addBooking = function(bookingObj, cb){
var newBooking = new Booking(bookingObj);
newBooking.save(cb);
}
There are no errors appearing in console, and i am not quite sure where to start looking.
Thanks in advance!
EDIT
The result from db.bookings.getIndices() is shown in the screenshot here
From the getIndices output I could see you've created an TTL index on dateOfBooking so it gets deleted after 60 seconds in the backend
From the mongo docs TTL index
TTL indexes are special single-field indexes that MongoDB can use to
automatically remove documents from a collection after a certain
amount of time or at a specific clock time

Create subsubdocs in Mongoose with Nested Schema

I have a User Schema that includes nested Schemas - overall three layers deep. I have no problem adding to Polls, but cannot add Inputs for the life of me. I have tried to get a user then handle the data like regular json (such as getting the index of the polls array and then pushing to the nested input array). I have tried creating a new input and pushing it to the inputs array.
The following code works perfectly for creating a new poll on a given user:
const poll = user.polls.create({});
user.polls.push(poll);
user.save(function(err, data) {
//more stuff here
})
However, when I try the same method on polls, I cannot save to the DB.
const poll = user.polls.id(<some _id>);
const input = poll.create({}); // or user.polls.id(<some _id>).create({});
poll.inputs.push(input);
I have gone back and forth and tried several things and cannot seem to get this to work given my current data structure. I have read several posts on SO as well as other online sources but most give examples for the first embedded subdoc, not the subdoc of the subdoc. Any help you can provide would be greatly appreciated. Thanks. I'm thinking of scrapping Mongoose on this project and just using the mongodb package for clearer control over what is going on with my data.
Here's my current code:
From User.js
const InputSchema = new Schema({
[ALL SORTS OF VARIOUS DATA HERE]
});
const PollSchema = new Schema({
inputs: [InputSchema],
});
const UserSchema = new Schema({
polls: [PollSchema]
});
module.exports = mongoose.model('User', UserSchema);
From controllers.js
const User = require('../models/User');
router.post('/polls/inputs/add/:creatorId', function(req, res) {
let title = req.body.option.title,
order = req.body.option.order,
voters= [];
User.findOne({ creatorId: req.params.creatorId })
.then(user => {
const input = {order, title, voters};
user.polls.id(req.body.pollId).inputs.push(input);
user.save(function(err, data) {
if (err) {
res.statusCode = 500;
return res.json({ title: 'Save Error', message: err });
}
console.log('Success!');
res.json({ input: input });
});
}).catch(err => {
res.statusCode = 500;
return res.json({ title: 'DB Error', message: err });
});;
});
Mongoose isn't able to track changes in subobjects like this, so the field must be marked explicitely as needing to be updated like so:
user.markModified('polls')

Mongoose not saving document completely

I am trying to save data to my mongo db using mongoose. But unfortunately I am not able to save it completely. However it creates a data array but defaults like company name etc. are not saving. However these values are not available in requested body
I am using:
var seller = new sellers(req.body);
seller.save(function (err) {
if (err) {
return res.status(500).send('An user with this email id or mobile number already exist');
}
res.status(200).send('You have successfully registered');
})
In this case you could use a pre save hook to set an object as the default in your array:
userSchema.pre('save', function(next) {
if (this.data.length == 0) {
var default = {
fieldName: 'Company Name',
fieldValue: 'No Information Provided',
// etc.
};
this.data.push(default);
}
next();
});

Resources