javascriptnode.jsexpress-sessionnode-inspector

How to track req.session variable with node-inspector to understand how a session object gets removed from request.session


//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

enter image description here 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


Solution

  • 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.