How to update a record in mongo db using node js - node.js

I have created a simple signup and login using node js and mongoDb. I can successfully do signup and login and now I want to add some more data to the user model after logging in from the secret page. How can I do that?
This is my user model and I want to add some text to user.text field after loggin in:
var mongoose = require("mongoose");
var UserSchema = mongoose.Schema({
username: String,
password: String,
text:String
});
module.exports = mongoose.model("User", UserSchema);
This is my view page (i.e., the secret page)
<h1>Hi, <%= user.username %></h1>
<form action="/birthday" method="post">
<input type="text" name="text">
<button type="submit">Update database</button>
</form>
The text should be shown here after updating.
Thanks!

You need to make an API on the node process to send the data to. I suggest you take a look at stuff like Express.js and google about REST API:s.

Related

How to store and retrieve checkbox state on refresh of page? Mongoose/EJS/Nodejs/Express

I have a checkbox, essentially like a to do list. When i check the box, I want to retain the state even after i refresh the page by using mongoose. I do know of localstorage, however EJS runs on a server side. Currently I am able to post the checkbox to my express side.
IN EJS
form id="form2" action="/check" method="post"></form>
<input form="form2" type="checkbox" name="checkboxx" onChange="this.form.submit()">
IN EXPRESS
app.post("/check", function(req,res){
Item.updateOne({checked: req.body.checkboxx.checked}, function(err){
if(err){
console.log(err);
} else console.log("successfully updated db")
})
res.redirect("/")
})
My collection is "Item", the schema includes a boolean property "checked"
checkboxx is the name of the input checkbox.
Any way to update the information of the checkbox state and reload the saved states upon refreshing the page?
In my case, the user profile page is also a form for data entry. (I save the form values with mongoose on a Mongo Atlas db, so some steps are skipped here.)
In my profile.ejs page, the toggleswitch is :
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="onOffSwitch" id="onOffSwitch" <%= params.onOffSwitch ? "checked" : "" %> >
<label class="custom-control-label" for="onOffSwitch">Activate</label>
</div>
And in my Express app the route is :
app.post(`/api/params`, isLoggedIn, (req, res) => {
const email = req.user.email;
const onOffSwitch =req.body.onOffSwitch;
});
res.redirect(`/profile`);
});
Even after a log out and re-login, the checkbox value gets releaded correctly.

How can I access an object from a Mongoose Schema through the form?

I have this mongoose schema:
var mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
let userSchema = new mongoose.Schema({
username:
{type: String,
unique: true
},
password: String,
privileges:
{
region: [Number],
read: [Boolean],
write: [Boolean],
edit: [Boolean],
delete: [Boolean]
}
});
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema);
and I'm using this with the following form:
<form action="/register" method="POST">
<input type="text" name="username"><br/>
<input type="password" name="password"><br/>
<input type="text" name="privileges.region"><br/>
<input type="text" name="privileges.read"><br/>
<input type="text" name="privileges.write"><br/>
<input type="text" name="privileges.edit"><br/>
<input type="text" name="privileges.delete"><br/>
<button>Submit</button>
</form>
I suppose the name is okay because privileges is an object, so every property should be accessed with the dot notation. If it's not, please let me know.
req.body looks like this:
When I try to console.log(req.body.privileges.region) or any other property, I get undefined. How should I access one of the privileges objects properties? Thanks.
The keys for the dictionary coming back on the request are actually the strings: 'privileges.region', 'privileges.delete', etc. So you must access them as
req.body['privileges.region']
People will generally write a helper function that handles this sort of notation to map it back their original model. Or they might do the mapping when the form is submitted in the browser in order to get the data in the shape you really want it:
{username
permissions:{region, ...}
...
}

How do I update a specific document from a form through mongoose?

Struggling with this problem because I'm missing some fundamentals I think, but after hours looking through the docs I think I need some help :)
I have a (simplified) collection as so:
const ExampleSchema= new Schema ({
Word: String,
Difficulty: String,
)};
Which I am succesfully displaying on a page as so:
<% ExampleSchemas.forEach(exampleschema=> { %>
<p><%= exampleschema.word %></p>
<p style="display: none" name="ExampleSchemaID" value="<%= ExampleSchema._id %>"</p>
<% }) %>
For each word I have a form below, I would like the user to be able to select easy, ok or hard and for this to set the value in the DB.
<form method="PUT">
<button formaction="/review/feedback/easy">Easy</button>
<button formaction="/review/feedback/ok">Ok</button>
<button formaction="/review/feedback/hard">Hard</button>
/form>
I have played around with a route like this to no avail
router.put("/review/feedback/easy", function (req,res){
var ID = req.body.ExampleSchemaID;
ExampleSchema.findByIdAndUpdate(
req.params.ExampleSchema._id,
req.Difficulty= easy);
The further issue is that I would like to display x number of these documents to the user, therefore I need a route that gets only that specific word.
router.put("/review/feedback/easy", function (req,res){
var ID = req.body.ExampleSchemaID;
ExampleSchema.findByIdAndUpdate({"_id": req.params.ExampleSchema._id},{"Difficulty": "3"});
but please not your difficulty is a number, so why not use a number instead:
const ExampleSchema= new Schema ({
Word: String,
Difficulty: Number,
)};
router.put("/review/feedback/easy", function (req,res){
var ID = req.body.ExampleSchemaID;
ExampleSchema.findByIdAndUpdate({"_id": req.params.ExampleSchema._id},{"Difficulty": 3});

Getting "Cannot POST" with registration page using Sequelize

I'm sure there's a sound reason as to why I can't get this to work but I've been staring at the code for a long time and I'm brutally stuck. I'm trying to build out a very basic registration form that should store the data in my PostgreSQL database. I'm using bcrypt to hash out the password, but even without still having issues.
My HTML has the following:
<form action="/register/new" method="post">
<label for="username">Username</label>
<input type="text" name="username">
<label for="password">Password</label>
<input type="password" name="password">
<label for="confirm">Confirm Password</label>
<input type="password" name="confirm">
<button type="submit">Submit</button>
</form>
Then for the code I have:
app.get("/register", function(req,res){
res.render("register");
})
app.post('register', function(req,res){
let newUser = {
username: req.body.username,
passwordHash: bcrypt.hashSynce(req.body.password, 8)
}
models.Users.create(newUser).then(function(){
res.redirect('/login');
})
});
The plan for the registration data to be stored and the user redirected to the login page, login stores them in session, and so on. I thought for a bit that the issue was the action on the form but regardless I'm getting Cannot POST /register/new. I've also played around with doing a findOrCreate and do a comparison but I wanted to start with actually just creating before I make it more complex. The same issue occurs with cannot post.
Any thoughts on what I need to change?
Probably would've worked better if I did a app.post("/register"...
Simple miss of an "/"
try this modified code...
app.post('/register', function(req,res) {
let newUser = {
username: req.body.username,
passwordHash: bcrypt.hashSync(req.body.password, 8)
}
// if it does not connect/save try using models.User instead of models.Users below.
models.Users.create(newUser).then(function(){
res.location('/login');
res.redirect('/login');
})
});

Does nodejs have a form helper similar to that of ruby's to generate CSRF tokens?

In ruby one can do something like <%= form_tag(:action => '/submit') do %> ... <% end %> to get a form including CSRF tokens.
Is there an existing function in node and how is it implemented?
You can use caolan-forms plugin for node.js. After that install express-csrf plugin.
Then you can merge these two, something like:
// initializing express
var express = require('express'),
// initializing express-csrf
csrf = require('express-csrf');
app = express.createServer();
app.dynamicHelpers({
csrf: csrf.token
});
var forms = require('forms'),
fields = forms.fields,
validators = forms.validators;
var reg_form = forms.create({
username: fields.string({required: true, id: csrf, name: csrf}),
});
// finally render the form
reg_form.toHTML();
It would produce:
<div class="field required">
<label for="id_username">Username</label>
<input type="text" name="[csrf-value]" id="[csrf-value]" value="test" />
</div>
Note: The caolan-forms' author wrote:
You'll notice you have to provide your own form tags and submit button, its more flexible this way ;)
Edit
Since express-csrf is depriciated, instead use connect bundle and follow this simple example. Eventually, you would be able to integrate it with caolan-forms like:
var reg_form = forms.create({
'_csrf':fields.hidden({value: 'req.session._csrf'}),
...
})

Resources