I am finding a trouble to set a session with node.js using express4.2.0 I show you my code and after I comment:
APP.js
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var cookieSession = require('cookie-session');
var mainModel = require('./model/main_model');
var users = require('./routes/users');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieSession({
keys: ['secret1', 'secret2']
}));
app.use('/users', users);
/*Evething that express makes automatically*/
app.listen(8080);
USERS.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res)
{
if(req.cookie && req.cookie.user) res.send("COOKIE");
else if(req.session && req.session.user) res.send("SESSION");
else res.render('users/new_user', {title:"NEW USER"});
});
/*there is more content... but not relevant. */
function makeTheUserSession(result, res)
{
result['go'] = '/users';
//res.session.user = result.result[0];
//res.cookie('user', result.result[0]);
res.send(result);
}
The function makeTheUserSession is call from the method post of '/users' (to find a users on the data base).
If I uncomment the res.session.user line, when I invoque makeTheUserSession the app breaks, stop, capito, dead (Cannot set property 'user' of undefined)...
If I uncomment the res.cookie('user', result... line, when I invke the function, and after I see the browser cookies on the settings I found a cookie called user with the values of result.result[0]... but after on the get method it doesn´t works how I expect... res never sends me "COOKIE".
I had sawn the same question many times repeated, but I didn´t see a answer that worth for me: some ones talk about connect middleware (I am using express), other say to use "app.use(express.session(keyword)) but it only works with the old version of express. The express-session module is deprecated, and I would want to use a more actuallity middleware.
I hope your answers. Thank you very much.
It's req.session not res.session, fix that and you should be good to go.
Related
Working with Registration in a Site. For the register Form,Validation is done using mongoose models and trying to Use Flash to display the error message in the Form.
But struct at this error
TypeError: res.flash is not a function
at /home/work/first-node-app/firstnode/routes/index.js:35:11
My Code snippets Follows below
App.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var flash = require('connect-flash');
var indexRouter = require('./routes/index');
var commonKeys = require('./config/config');
var app = express();
//connect mongoDb
mongoose.connect('mongodb://localhost:27017/db', { useNewUrlParser: true });
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// required for passport session
app.use(session({
secret: 'secrettexthere',
saveUninitialized: true,
resave: true,
// using store session on MongoDB using express-session + connect
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use('/', indexRouter);
module.exports = app;
Index.js
var express = require('express');
var router = express.Router();
var passport = require('passport');
var User = require('../models/user-model');
var Local = require('../config/passport-local');
router.get('/register', function(req, res){
res.render('public/register',{title:'Register'});
});
router.post('/register', function(req,res,next){
User.create({name:req.body.name, password:req.body.password, email : req.body.email}, function(err, user){
if (err) {
console.log('Error Inserting New Data');
if (err.name == 'ValidationError') {
for (field in err.errors) {
res.flash(field, err.errors[field].message);
}
res.render('public/register');
}
}
if(user) {
res.send('user registered');
}
})
});
module.exports = router;
Can anyone point out the error in this code snippets, as am new to Nodejs and Trying to work out the Form validation. The validation Works fine and the console displays the error but i can't pass that using flash. Can anyone Help me? And its much appreciated if you confirm my approach to code Nodejs is in correct way.
Use req.flash() in place of res.flash. Refer here for more clarification.
When I run the following:
const express = require('express');
const bodyParser = require('body-parser');
const routes = require("./routes.js");
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(routes);
var port = process.env.PORT || 3000;
app.listen(port);
I get:
TypeError: app.use() requires a middleware function.
The console says the error occurs at the u in app.use(routes);. However if I run:
var express = require('express');
var bodyParser = require('body-parser');
var clientSessions = require('client-sessions');
var routes = require("./routes");
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/', express.static('./'));
app.use('/js', express.static('./public/js'));
app.use('/CSS', express.static('./public/CSS'));
app.use('/images', express.static('./public/images'));
app.use('/views', express.static('./public/views'));
app.use(clientSessions({
secret: 'ugkgdiuwgbkbgjwjkgvo'
}));
app.use(routes);
var port = process.env.PORT || 3000;
app.listen(port);
From a different project, that project works fine which leads me to believe there is something wrong with my current project.
However I cannot figure out what. I've tried looking at several other problems similar to mine but none of their solutions helped. Thanks in advance!
routes.js (following a request by #31piy):
var express = require("express");
var router = express.Router();
router.get("/signup",function(request,response){
response.sendFile(__dirname + "/Client/HTML/signup.html");
});
router.post("/signup",function(request,response){
});
router.get("/login",function(request,response){
response.sendFile(__dirname + "/Client/HTML/login.html");
});
You need to export the “router” from routes.js in order for it to work.
In your case add this line at the end of routes.js
module.exports = router;
That way app.use would be using an actual instance of router.
If you make a router function in different js file
It is needed to be exported so that your app.js can use it.
module.exports=router
This will help
im trying to get a form to submit some data to my express app.js without the page reloading. I thought i had the correct code but when it comes to getting the code from the ajax call to the server i get a undefined data variable.
app.js: (removed irrelevant lines)
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.get('/web_text.json',function(req, res, next){
res.sendFile(__dirname + '/web_text.json');
});
app.post('/sendEmail', function (req, res) {
console.log(req.body.data);
});
app.use('/', index);
module.exports = app;
jquery function that makes ajax call:
$('#reserve form').on('submit', function(){
event.preventDefault();
var data = {
name: $('#name').val()
};
console.log(data);
$.ajax({
url: 'http://localhost:3000/sendEmail',
data: data,
method: 'POST'
}).then(function (response) {
// Do stuff with the response, like add it to the page dynamically.
$('body').append(response);
}).catch(function (err){
console.error(err);
});
});
note the console.log()s in my /sendEmail app.post function and the one in the jquery function. the jquery one logs the correct data while the app.post one logs a undefined variable... what am i doing wrong? thanks in advance
Your jQuery is not POSTing JSON, it is sending a JS object. I would be willing to bet this is a content type issue.
You might also want to look into $('#reserve-form').serialize() to package up your form data for sending instead of trying to manually create your object.
in your app.js you didn't send the response. That is why you get undefined output. try this
app.post('/sendEmail', function (req, res) {
console.log(req.body.data);
res.jsonp({data: 'your data'});
});
Hope this will help you.
A Newbie question I guess. I want to set and get cookies on my express site.
cookieParser is set up and seems to run. But my cookies are always undefined. So what can be wrong? Doesn't cookies work on localhost?
I can access all cookies in the console on chrome.
I have tried both httpOnly: false/true.
Here's my code:
var express = require('express'),
exphbs = require('express-handlebars'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
request = require('request'),
livereload = require('express-livereload'),
port = Number(process.env.PORT || 3000);
var log = require('./lib/log.js'));
var app = express();
livereload(app, config = {watchDir: process.cwd()});
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(express.static('public'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true}));
app.get('/', function(req, res) {
res
.cookie('cart', 'test', {maxAge: 900000, httpOnly: false})
.render('index');
console.log(res.cookie.cart);
});
app.listen(port, function() {
log.clear();
log.out('Express on http://localhost:' + port);
log.hr();
});
Any clues?
Maybe you should change:
console.log(res.cookie.cart);
to:
console.log(req.cookies.cart);
I just wrote a simple example that demonstrates what's going on:
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/', function(req, res) {
var oldCookie = req.cookies.test;
var newCookie = (oldCookie|0) + 1;
res.cookie('test', newCookie, {maxAge: 900000});
res.status(200).json({
newCookie: newCookie,
oldCookie: oldCookie,
reqCookie: req.cookies.test,
});
});
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
When you run it and go with your browser to http://localhost:3000/ you will see:
{"newCookie":1}
When you reload the page you will see:
{"newCookie":2,"oldCookie":"1","reqCookie":"1"}
Here's what's going on: In the first request even though you set the cookie in you handler before printing it it is not really set yet - it is just queued to be passed to the client in the response with an HTTP header like this one:
Set-Cookie: test=1; Max-Age=900; Path=/; Expires=Wed, 21 Sep 2016 13:03:06 GMT
In the second request you see the old value in reqCookie and the new value in newCookie - those values are different. Seeting the cookie doesn't change the one that you got in the request. I even included the reqCookie which is not stored in a variable but accessed directly from req.cookies during the res.end() invocation to demonstrate that it is not changed.
app.js
var express = require("express");
var app = express();
var path = require('path');
var db = require('./db');
var bodyParser = require('body-parser');
app.listen(80);
app.set('view engine', 'jade');
app.set('views', "./views");
// app.get('/', _GetMainPage);
// app.get('/sites', _GetSites);
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true })); // Support encoded bodies
app.use(bodyParser.json()); // Support json encoded bodies
app.use(require('./controllers'));
./controllers/index.js
var express = require('express');
var router = express.Router();
router.use('/', require('./sites'));
router.use('/site', require('./site'));
module.exports = router;
./controllers/sites.js
var express = require('express');
var router = express.Router();
var site = require('../models/site');
router.get('/', function(req, res) {
site.getAll(function(err, rows){
if(err) {
res.send(err);
return;
}
res.render('sites', { sites : rows });
});
});
./controllers/site.js
var express = require('express');
var router = express.Router();
var site = require('../models/site');
router.get('/site', function(req, res) {
// console.log("get /site received. req.body: " + req.body);
res.render('site', {
site: {
name : req.params.name
}
});
});
module.exports = router;
When I request localhost/site I get a response saying:
Cannot GET /site
localhost/ works perfectly
I have been looking at this for a while and can't find the problem yet. If there is anything I can add, let me know. Thanks.
Thank you to the person that commented with the answer:
What happens if you navigate to /site/site? Your site.js route is relative to the route you provided in use. So it should be router.get('/' ... not router.get('/site' ...
The ./controllers/site route is already being routed to /site. On top of this I was calling router.get('/site', ...). This means it was actually routing to /site/site.
The solution is to just use router.get('/', ...) in the site.js file instead.
This really helped me, thank you.
Basically, the root path in the sub-app is defined in your core app where you mount it via the app.use() method.
the best example I can find from app.mountpath docs is here:
https://expressjs.com/en/4x/api.html#express.router
The app.mountpath property contains one or more path patterns on which a sub-app was mounted.
var express = require('express');
var app = express(); // the main app
var admin = express(); // the sub app
admin.get('/', function (req, res) {
console.log(admin.mountpath); // /admin
res.send('Admin Homepage');
});
app.use('/admin', admin); // mount the sub app
It is similar to the baseUrl property of the req object, except
req.baseUrl returns the matched URL path, instead of the matched
patterns.
If a sub-app is mounted on multiple path patterns, app.mountpath
returns the list of patterns it is mounted on, as shown in the
following example.
var admin = express();
admin.get('/', function (req, res) {
console.log(admin.mountpath); // [ '/adm*n', '/manager' ]
res.send('Admin Homepage');
});
var secret = express();
secret.get('/', function (req, res) {
console.log(secret.mountpath); // /secr*t
res.send('Admin Secret');
});
admin.use('/secr*t', secret); // load the 'secret' router on '/secr*t', on the 'admin' sub app
app.use(['/adm*n', '/manager'], admin); // load the 'admin' router on '/adm*n' and '/manager', on the parent app