//Initializing session
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
//cookie: { secure: true }
}));
I was creating a shopping cart and came across a problem , I was setting cart object in session
req.session.cart = [];
//then
req.session.cart.push({
title : p.title,
price : p.price,
image : '/static/Product_images/'+p._id+'/'+p.image,
quantity:quantity,
subtotal : p.price
});
after that I tried consoling that and I was getting the session variable with cart object inside it but after that while I tried setting it to app.locals.cart
for using it with ejs , by trying to get req.session from inside a get method of the express module but the req.session.cart gives undefined.
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
// console.log("New cart variable");
//console.log(req.session);
//console.log(req.locals);
//console.log(req.app.locals.cart);
if(req.session.cart!=="undefined"){
app.locals.cart=[];
app.locals.cart = req.session.cart ;
}
next();
});
I was unable to understand why the session variable was losing the cart object
after going through some of questions in StackOverflow I found nothing that solves my dilemma .So I decided to stop using simple console.log but instead I decided to use the nodejs inspector and I installed I ran
node --inspect app.js
But the problem here I faced is that it limited its access to app.js itself the adding shopping cart functionality is in routes/cart.js
I wanted to track the flow of requests using nodejs inspector module and find out why the cart variable is removed from the session variable every time
So my question is of two part ,first part :- why is the sources folder only showing app.js instead of the whole project like in this simple tutorial
I am not getting the project and files inside it to set debug points and source only has app.js as default loaded source
second part is why is cart object getting removed from session without any reason
EDIT:-
cart.js
I know one the first pass it will be undefined but on second path it will not be since it will be set by
var productModel =require('../models/products.js');
var categoryModel =require('../models/category.js');
module.exports=(app)=>{
app.get('/add-to-cart/:id',function(req,res){
console.log("Cart get started");
var quantity,subtotal = 0;
productModel.findOne({'_id':req.params.id},function(err,p){
//console.log("product consoled"+p);
if(err){
return console.log(err);
}
if( typeof req.session.cart == "undefined"){
//console.log("Session undefined check");
quantity=1;
req.session.cart = [];
req.session.cart.push({
title : p.title,
price : p.price,
image : '/static/Product_images/'+p._id+'/'+p.image,
quantity:quantity,
subtotal : p.price
});
console.log("#### The request var session inside cart function start");
console.log("#### The request var session var end");
req.app.locals.cart=[];
req.app.locals.cart.push({
title : p.title,
price : p.price,
image : '/static/Product_images/'+p._id+'/'+p.image,
quantity:quantity,
subtotal : p.price
});
//console.log(req.app.locals);
//console.log("Session set ");
//console.log(req.session.cart);
console.log("Cart got set");
console.log(req.session);
}else{
var product = req.session.cart;
var productFound = false;
product.forEach(function(prod){
if(prod.title==p.title){
prod.quantity+=1;
prod.subtotal=prod.quantity*prod.price;
productFound=true;
}
});
req.session.cart=product;
if(!productFound){
quantity=1;
req.session.cart.push({
title : p.title,
price : p.price,
image : '/static/Product_images/'+p._id+'/'+p.image,
quantity:quantity,
subtotal : p.price
});
}
}
}); console.log("req.session.cart");
console.log(req.session.cart);
req.flash('success','product added to cart');
res.redirect('back');
});
}
EDIT 1:- I tracked the sessionId across the calls and found it to be same ruled about possibility of creation of new session but still what removes the cart object from session object remains a mystery
The session corresponding to that sessionId is fetched from server and attached to req object as req. session. It gives a feel that we are getting session from client side, but actually it is the work of middleware to attach session object to req object by getting the cookie from the client.
server. js var express = require('express'); var session = require('express-session'); var app = express();
saveUninitialized : When an empty session object is created and no properties are set, it is the uninitialized state. So, setting saveUninitialized to false will not save the session if it is not modified. The default value of both resave and saveUninitialized is true, but using the default is deprecated.
Cookies can only hold strings, but you're trying to initialize your cookie as an array and then push objects into it. A cookie will only do a basic "key":"value"
.
req.session.cart = {
title : p.title,
price : p.price,
image : '/static/Product_images/'+p._id+'/'+p.image,
quantity:quantity,
subtotal : p.price
}
If you wanted to have it nested, that you'd likely have to use something JSON.stringify()
to serialize it on a single key and deserialize it to look at the full object. So long as you keep your cookie below that max size.
Edit:
So although what I wrote holds true about cookies, it doesn't correctly address that express-sessions
actually stores the data server-side and only stores the session id in the cookie.
In running an Express application using express-generator
using node --inspect ./bin/www
, you get the option to using Chrome's native NodeJS inspector. You should be able to view sources from the dedicated Node Inspector and see your entire directory from there.
Without seeing your full application structure, its hard to determine why you would only be seeing your app.js
file, since Node will include all referenced files when inspecting. Presumably, the reason you're not seeing your routes is because you're passing your application to them, rather than including the routes within your main application (see below).
const indexRouter = require('./routes/index');
const cartRouter = require('./routes/cart');
const app = express();
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
//cookie: { secure: true }
}))
app.use('/', indexRouter);
app.use('/cart', cartRouter);
The only way that I could replicate your issue of the cart constantly disappearing was if I was using http
and had cookie: { secure: true }
not commented out.
You may use a Proxy object and track down any mutations taking effect within the session.
const debugHandler = {
get: function(target, property) {
console.log('getting ' + property + ' for ' + target);
// property is index in this case
return target[property];
},
set: function(target, property, value, receiver) {
console.log('setting ' + property + ' for ' + target + ' with value ' + value);
target[property] = value;
// you have to return true to accept the changes
return true;
}
};
req.session.cart = new Proxy([], debugHandler);
throw new Error()
while mutating the object will pop the exact stack trace.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With