I am new in Node Js and trying to learn it. I am currently follow this tutorial: http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/ but its incomplete.
I want, if I click on any user from the list of users, it will take me to new page and show the record in form for update. I don't know how to send data onclick, find the record from the db and show it inside a form to update.
Here is the index file with all the functions:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
/*Get Hello world page*/
router.get('/helloword', function(req, res){
res.render("Helloworld", {title:'Hello, World!'});
});
/*Get UserList*/
router.get('/userlist', function(req, res){
var db = req.db;
var collection =db.get('usercollection');
collection.find({}, {}, function(e, docs){
res.render('userlist',{
"userlist": docs
});
});
});
/*Get New User Page*/
router.get('/newuser', function(req, res){
res.render('newuser',{title: 'Add New User'})
});
/* POST to Add User Service */
router.post('/adduser', function(req, res) {
// Set our internal DB variable
var db = req.db;
// Get our form values. These rely on the "name" attributes
var userName = req.body.username;
var userEmail = req.body.useremail;
// Set our collection
var collection = db.get('usercollection');
// Submit to the DB
collection.insert({
"username" : userName,
"email" : userEmail
}, function (err, doc) {
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// And forward to success page
res.redirect("userlist");
}
});
});
module.exports = router;
Thanks in advance please help me for guidance
It looks like you want to use findAndModify (docs)
Using your code you could implement an update route like so.
router.post('/user/:userId', function (req, res) {
// Set our internal DB variable
var db = req.db;
// Get our form values. These rely on the "name" attributes
var userName = req.body.username;
var userEmail = req.body.useremail;
// Set our collection
var collection = db.get('usercollection');
collection.findAndModify(
{_id: req.query.userId}, // query
[['_id', 'asc']], // sort order
{
$set: {
"username": userName,
"email": userEmail
}
}, // replacement
{}, // options
function (err, object) {
if (err) {
console.warn(err.message); // returns error if no matching object found
} else {
console.dir(object);
}
});
});
However this does not have any validation to make sure that the user has the correct permissions to update this, make sure you add something like the query
{$and: [{_id: req.query.userId}, {createdBy: req.user}]}
Related
I am currently using Passport for authentication within my application. When trying to pull a users email in order to store in my db along with other information, I get a returned value of undefined. If I pull the entire user object I get the correct information though. See below.
Here is the server.js file initializing the session.
app.use(session({
secret: 'sessionSecret'
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
Here is the route information
app.get('/itemCreation', function (req, res) {
res.render('itemCreation.ejs', {
user: req.user
});
});
app.post('/itemCreation', function (req, res) {
var item = new itemSchema();
item.local.productName = req.body.productName;
item.local.itemPrice = req.body.itemPrice;
item.local.Quantity = req.body.Quantity;
item.local.Description = req.body.Description;
console.log(req.user.firstName);
item.save(function (err) {
if (err)
throw err;
else
console.log('Saved item information successfully');
});
res.redirect('/shop');
});
Here is my Item model
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var itemSchema = mongoose.Schema({
local : {
productName : String,
itemPrice : Number,
Quantity : Number,
Description : String
}
});
module.exports = mongoose.model('item', itemSchema);
Here is the result of pulling the whole object, which I get by calling
console.log(req.user);
and here is the result of pulling just the email from the object, which I get by calling
console.log(req.user.email);
It shoud be console.log(req.user.local.email);
I am struggling since I am trying to retrieve all the parameters of a POST request in node.js, but it's not gonna work.
Here the post request from the webpage:
var email = $('#email').val();
var name = $('#name').val();
var surname = $('#surname').val();
var role = $('#role').val();
var telephone = $('#telephone').val();
var description = $('#description').val();
$.post('/user/save', {
email : email,
name : name,
surname : surname,
role : role,
telephone : telephone,
description : description
})
.done(function(){
alert('<h2>The new user has been successfully added!</h2>', function(){
clearUserFields();
window.location.reload();
});
})
.fail(function(){
alert('<h2>Sorry, an error occurred during the operation.<br>Please retry later...</h2>', function(){
window.location.reload();
});
});
And this is the route in node.js
// routes file
var postgresql_db_controller = require('../controller/compose-postgresql-connection');
var Q = require ('q');
var bodyParser = require('body-parser');
// route for editing the user
/*
app.get('/user/edit', function(req, res){
retrieveUserInfo().then(function(result){
res.render('admin-profile.ejs', {
title : 'Edit your profile',
admin-info: result
});
});
});
*/
module.exports = function (app) {
// route for routing to "adding a new user" page
app.get('/user/add', function(req, res){
res.render('new-user-profile.ejs', {
title : 'Add a new user'
});
});
//route for routing to "editing the admin user info" page
app.get('/user/admin', function(req, res){
res.render('admin-profile.ejs', {
title : 'Admin profile'
});
});
// route for adding and storing a new user into the postgresql databases
app.post('/user/save', function(req, res){
console.log("routes");
console.log("req.body : " + req.body);
var email = req.params.email;
var name = req.params.name;
var surname = req.params.surname;
var role = req.params.role;
var telephone = req.params.telephone;
var description = req.params.description;
// storing data into database
postgresql_db_controller.postgresql_save_user(email, name, surname, role, telephone, description).then(function(result){
if(result == null){
res.writeHead(404);
res.end();
return;
}
// TO DO
// manage the result (?)
console.log(result);
res.writeHead(200);
res.end();
});
});
// route for creating a new project
// route for searching an existing project
};
and this is the other file:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
var Q = require ('q');
var cfenv = require('cfenv');
// Util is handy to have around, so thats why that's here.
const util = require('util');
// and so is assert
const assert = require('assert');
// Then we'll pull in the database client library
var pg = require('pg');
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();
// Within the application environment (appenv) there's a services object
var services = appEnv.services;
// The services object is a map named by service so we extract the one for PostgreSQL
var pg_services = services["compose-for-postgresql"];
// This check ensures there is a services for PostgreSQL databases
// assert(!util.isUndefined(pg_services), "Must be bound to compose-for-postgresql services");
// We now take the first bound PostgreSQL service and extract it's credentials object
var credentials = pg_services[0].credentials;
// Within the credentials, an entry ca_certificate_base64 contains the SSL pinning key
// We convert that from a string into a Buffer entry in an array which we use when
// connecting.
var ca = new Buffer(credentials.ca_certificate_base64, 'base64');
var connectionString = credentials.uri;
// We want to parse connectionString to get username, password, database name, server, port
// So we can use those to connect to the database
var parse = require('pg-connection-string').parse;
config = parse(connectionString);
// Add some ssl
config.ssl = {
rejectUnauthorized: false,
ca: ca
}
// set up a new client using our config details
var client = new pg.Client(config);
// This function to set up the connection with PostgreSQL database
module.exports.postgresql_database_connection = function() {
client.connect(function(err) {
if (err) {
console.log(err);
}
else {
client.query('CREATE TABLE IF NOT EXISTS users (email varchar(256) NOT NULL PRIMARY KEY, name varchar(256) NOT NULL, surname varchar(256) NOT NULL, telephone int NOT NULL, role varchar(256) NOT NULL, description varchar(256) NOT NULL)', function (err,result){
if (err) {
console.log(err);
}
});
}
});
};
// This function is to create and store a new user into the PostgreSQL database with all the needed information
module.exports.postgresql_save_user = function(email, name, surname, role, telephone, description) {
console.log("reading parameters");
var deferred = Q.defer();
// set up a new client using our config details
var client = new pg.Client(config);
client.connect(function(err) {
if (err) {
console.log(err);
deferred.reject();
}
else {
var queryText = 'INSERT INTO users(email,name,surname,telephone,role,description) VALUES(?, ?, ?, ?, ?, ?)';
client.query(queryText, [email, name, surname, telephone, role, description], function (error,result){
if (error) {
console.log(error);
deferred.reject();
}
else {
console.log("Saving the new user into the postegresql database: ");
console.log(result);
//check how result is printed and then manage it where called
deferred.resolve(result);
}
});
}
});
return deferred.promise;
};
It seems there is an error in:
req.params.email
it's not printing anything. I also tried to use req.body.param_name but nothing happen. You know what it is?
Thank you in advance
Try to wrap the data in JSON.Stringify as below.
$.post('/user/save', JSON.Stringify({ email : email, name : name, surname : surname, role : role, telephone : telephone, description : description }))
If you get any error at JSON.Stringify, try to use Json data directly as below.
$.post('/user/save', "{ 'email' : email, 'name' : name, 'surname' : surname, 'role' : role, 'telephone' : telephone, 'description' : description }")
your code does not make use of bodyParser
in app.js (where you start node server), just below var app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
And your route file
// routes file
var postgresql_db_controller = require('../controller/compose-postgresql-connection');
var Q = require ('q');
var bodyParser = require('body-parser');
// route for editing the user
/*
app.get('/user/edit', function(req, res){
retrieveUserInfo().then(function(result){
res.render('admin-profile.ejs', {
title : 'Edit your profile',
admin-info: result
});
});
});
*/
module.exports = function (app) {
// route for routing to "adding a new user" page
app.get('/user/add', function(req, res){
res.render('new-user-profile.ejs', {
title : 'Add a new user'
});
});
//route for routing to "editing the admin user info" page
app.get('/user/admin', function(req, res){
res.render('admin-profile.ejs', {
title : 'Admin profile'
});
});
// route for adding and storing a new user into the postgresql databases
app.post('/user/save', function(req, res){
console.log("routes");
console.log("req.body : " + req.body);
var email = req.body.email;
var name = req.body.name;
var surname = req.body.surname;
var role = req.body.role;
var telephone = req.body.telephone;
var description = req.body.description;
// storing data into database
postgresql_db_controller.postgresql_save_user(email, name, surname, role, telephone, description).then(function(result){
if(result == null){
res.writeHead(404);
res.end();
return;
}
// TO DO
// manage the result (?)
console.log(result);
res.writeHead(200);
res.end();
});
});
// route for creating a new project
// route for searching an existing project
};
Check req.body after console.log("routes"); of your server file and see what parameters you are getting.
like this:-
console.log(req.body)
if you have body parser package then it will show you parameters list which are coming out from client. Once you get the parameters list, you can easily get like req.body.email .
Also change your ajax request like this:-
$.post('/user/save', data: {
"email" : email,
"name" : name,
"surname" : surname,
"role" : role,
"telephone" : telephone,
"description" : description
})
.done(....
Also where is this code..
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
in your server file?
you need to add this in your app file to access bodyparser
I'm trying to create a Document Schema where I would have a dynamic Object. Example:
var ModuleSchema = new Schema({
name : String,
description : String,
type : String,
age : String,
options : {}
});
Is it possible to do the
options : {}
like that? with any arbitrary attributes inside. I'm getting TypeError: Cannot read property 'find' of undefined when I try to access a route /api/something to get all the documents in the collection. It might be because of the way I've defined the schema. any ideas?
EDIT:
var Module = require('../models/module');var auth =require('../config/auth');module.exports = function(router,Module){
router
.get('/api/modules' , auth.checkAuth, function(req,res){
Module.find(function(err,modules){
if(err){
res.send(err);
}else{
res.json(modules);
}
});
})
.post('/api/modules' , auth.checkAuth,function(req,res){
var module = new Module();
console.log(req.body);
module.name = req.body.name;
module.type = req.body.type;
module.description = req.body.description;
module.age = req.body.filename;
module.options = req.body.options;
module.save(function(err,module){
if(err){
res.send(err);
}else{
res.json({ id : module._id});
}
});
});
I use something like this.
// Importing the Users Mongoose Scheme
var User = require('../app/models/user');
var Feed = require('../app/models/ufeed');
module.exports = function(app) {
// A Route to get all users info
app.get('/user/all', function(req, res) {
// use mongoose to get all users in the database
User.find(function(err, user)
{
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
{
res.send(err);
}
// return all todos in JSON format
res.json(user);
});
});
Within my server.js file I am creating an app like so.
var app = express();
And then passing it to my routes file.
require('./app/routes.js')(app); // load our routes and pass in our app
I hope this helps.
I'm attemting to create an application to make restraunt reservations with Node, but currently my data from the database is not showing on the page. Here is the jade file of the page that is meant to display the data:
extends layout
block content
h1.
Reservations
ul
each reservation in reservations
li= reservation.lastName
li= reservation.numberOfPeople
Here is my index.js file:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/reservations', function(req, res) {
var db = req.db;
var collection = db.get('freshStart');
collection.find({},{},function(e,docs){
res.render('reservations', {
"reservations" : docs
});
});
});
router.get('/makeReservation', function(req, res){
res.render('makeReservation', { title: 'Make a reservation'});
});
router.post('/makeReservation', function(req, res){
var db = req.db;
var lastName = req.body.lastName;
var numberOfPeople = req.body.numberOfPeople;
var time = req.body.myTime;
var date = req.body.myDate;
var collection = db.get('freshStart');
collection.insert({
"lastName" : lastName,
"numberOfPeople" : numberOfPeople,
"time" : time,
"date" : date
}, function(err, doc) {
if(err) {
res.send("There was a problem adding the information to the database", err.toString());
} else {
res.redirect("reservations");
}
});
});
module.exports = router;
Yet when I load the page, it only shows the title but no database info. I've queried the data in cmd and it comes up with two entries. What am I doing wrong?
The error was I was refrencing the wrong part of the database. This was my code:
router.get('/reservations', function(req, res) {
var db = req.db;
var collection = db.get('freshStart');
collection.find({},{},function(e,docs){
res.render('reservations', {
"reservations" : docs
});
});
});
What I should have been doing is this:
router.get('/reservations', function(req, res) {
var db = req.db;
var collection = db.get('reservations');
collection.find({},{},function(e,docs){
res.render('reservations', {
"reservations" : docs
});
});
});
I have a basic express project created. And I've created a file called lib/userhandler.js inside root folder.
//lib/userhandler.js
exports.addUser = function(req, res){
// Set our internal DB variable
var db = req.db;
// Get our form values. These rely on the "name" attributes
var uName = req.body.username;
var uEmail = req.body.useremail;
// Set our collection
var collection = db.get('usercollection');
// Submit to the DB
collection.insert({
"username" : uName,
"email" : uEmail
}, function (err, doc) {
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// If it worked, set the header so the address bar doesn't still say /adduser
//res.location("userlist");
// And forward to success page
res.redirect("userlist");
}
});
}
In my routs/users.js file, whenever the users page is loaded I want to send name and the mail values throught userhandler.js to the database.
//routes/users.js
var express = require('express');
var router = express.Router();
var User = require("../node_modules/SimpleExpress/routes/userhandler.js");
var name = "testuser6";
var mail = "testuser6#testdomain.com";
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
User.addUser(name, mail);
});
module.exports = router;
When I try to load users page it shows "Can't set headers after they are sent."
Thank You
You should try to return the error from your db to your route handler through a callback like this :
//routes/users.js
var express = require('express');
var router = express.Router();
var User = require("../node_modules/SimpleExpress/routes/userhandler.js");
var name = "testuser6";
var mail = "testuser6#testdomain.com";
/* GET users listing. */
router.get('/', function(req, res, next) {
User.addUser(name, mail, function(err, doc) {
if(err) {
res.send("There was a problem adding the information to the database.");
} else {
res.redirect("userlist");
}
});
});
//lib/userhandler.js
exports.addUser = function(name, mail, cb){
// Set our internal DB variable
var db = req.db;
// Set our collection
var collection = db.get('usercollection');
// Submit to the DB
collection.insert({
"username" : name,
"email" : mail
}, function (err, doc) {
cb(err, doc);
});
}
You shouldn't insert the request and response objects as parameters of the function addUser(). They should be in the router callback function. I added a new parameter to the function, so that you can pass the database as a parameter thanks to the router which receives the request object as a parameter.
//lib/userhandler.js
exports.addUser = function(uName, uEmail, db){
var collection = db.get('usercollection');
var result = true;
collection.insert({
"username" : uName,
"email" : uEmail
}, function (err) {
if (err) {
result = false;
}
});
return result; // true or false
}
I changed the code here also, so that the name and email variables can be received from the req and res parameters.
//routes/users.js
var express = require('express');
var router = express.Router();
var User = require("../node_modules/SimpleExpress/routes/userhandler.js");
//var name = "testuser6"; // I don't think you need this
//var mail = "testuser6#testdomain.com"; // and this
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
var db = req.db;
var name = req.body.username;
var mail = req.body.useremail;
if(!User.addUser(name, mail, db)) {
res.send("There was a problem adding the information to the database.");
return;
}
res.redirect('userlist');
});
module.exports = router;
I haven't tested the code because I really don't have time but I hope it works fine.