Search code examples
javascriptjquerynode.jsexpressexpress-handlebars

Is it possible to access a Handlebar variable through an external .js file?


I hope all is well despite the pandemic we are experiencing right now. I am currently doing a school project and found myself stuck in an endless loop trying to figure things out. I am looking for a way how to access the data passed by my route handler to my handlebar template to my separate javascript file.

Please see attached code below:

index.js (the route handler which passes the variables to my handlebar template)

app.get('/', function(req, res){
    if (req.session.loggedin){
        professorModel.aggregate([{ $sample: { size: 3 } }]).then(function(qvProfs) {
            reviewModel.find({}).populate('profRef').populate('studentRef').sort({_id:-1}).limit(10).exec(function(err,mostRecent) {
                collegeModel.find({}).exec(function(err, col){
                    var colleges = [];
                    var reviews = [];

                    col.forEach(function(document){
                        colleges.push(document.toObject());
                    });

                    mostRecent.forEach(function(document){
                        reviews.push(document.toObject());
                    });

                    res.render('frontend/home',{
                        studentRef: req.session.studentRef,
                        idNum: req.session.idNum,
                        colleges: colleges,
                        data: qvProfs,
                        review: reviews,
                        title: 'Home',
                    });
                });
            });
        });
    }
    else{
        res.redirect('/login')
    };
});

Main layout (the layout being used by 'frontend/home')

<script src="/js/script.js"></script>

script.js (the external .js file to manipulate the html)

    var newReview = {
      profName: $('#revProfName').find(":selected").text(),
      profCourse: $('#revProfCourse').find(":selected").text(),
      studentRef: "{{req.session.studentRef}}",
      studentId: "{{req.session.idNum}}",
      reviewContent: $("textarea#revContent").val()
    };

Everytime I do a console.log(newReview), I always get {{req.session.studentRef}} and {{req.session.idNum}} and not the actual value. Any help would be greatly appreciated. Thanks everyone!


Solution

  • ok so looks like there is no direct way to get it working as the handlebar does not interpret the separate js files but here's a hack around.

    1st you will need to pass the data window scope inside the view file. to do that first register a helper function if you are passing json/javascript object data.

    more info regarding this can be found here.

    hbs.registerHelper('json', function(context) {
        return JSON.stringify(context);
    });
    

    2nd step: Inside your view file add the data to the window scope.

    // if both variables you are sending are objects
    window.studentRef = JSON.parse('{{{json studentRef}}}');
    window.studentId = JSON.parse('{{{json studentRef}}}');
    // if the variables you are sending are int or string
    window.studentRef = {{studentRef}};
    window.studentId = "{{studentRef}}";
    

    Then you can access these from windows scope inside your js file on window load listener.

    // inside your js file
    window.addEventListener('load', () => {
    
        var newReview = {
          profName: $('#revProfName').find(":selected").text(),
          profCourse: $('#revProfCourse').find(":selected").text(),
          studentRef: window.studentRef,
          studentId: window.studentId,
          reviewContent: $("textarea#revContent").val()
        };
    })
    

    hope you got the idea of achieving it.