Mohammed Gadiwala
Mohammed Gadiwala

Reputation: 2073

How to pass session variable from express/node to angular?

So basically I am using angular routes and just using express to render the index page.

I want to pass a session variable from express to angular but I dont know how to get that variable in each route of angular.

app.js(express):

app.get('*', function (req, res) {
    res.sendFile(__dirname+'/client/views/index.html',{
        isAuthenticated:req.isAuthenticated(),
        user:req.user
    });
});

Index.html

<body>
<div class="main" ng-view>
    </div>
  </body>

Angular application file:

var myapp=angular.module('myApp', ['ngRoute','ngStorage']);
myapp.controller('contrl1', ['$scope' ,'$localStorage','$http', 
  function ($scope,  $localStorage,$http) {

  }]);
myapp.controller('contrl2', ['$scope' ,'$localStorage','$http', 
      function ($scope,  $localStorage,$http) {

      }]);
myapp.config(function($routeProvider, $locationProvider) {
  $routeProvider
   .when('/try', {
    templateUrl: '../views/view1.html',
    controller: 'contrl1',
  })
  .when('/hello', {
    templateUrl: '../views/view2.html',
    controller: 'contrl2',

  // configure html5 to get links working on jsfiddle
  $locationProvider.html5Mode(true);
});

So basically I want to send Isauthenticated variable and user variable which will be having session values, from express to angular.How should I proceed with that such that these values are accessible to all the routes in angular and also how to get those values in respective angular controller.

Upvotes: 1

Views: 8645

Answers (2)

Datsik
Datsik

Reputation: 14824

I don't believe this is possible.

Even when using sendFile you can still use any sort of templating stuff you want inside your file, as long as you have your view engine set.


You could either store it in a maybe hidden element, and then just use js to get the information from it or I think angular uses something like services to load this type of data after your controller loads

<input type="hidden" id="auth" value="#{authenticated}"/>

Then just use JavaScript to get the value once the controller loads

But this is hacky and not really the angular way of doing things. I'm pretty sure you should use services for this.

Upvotes: 1

Dave Amit
Dave Amit

Reputation: 2319

    app.get('*', function (req, res) {
        res.sendFile(__dirname+'/client/views/index.html',{
            isAuthenticated:req.isAuthenticated(),
            user:req.user
        });
    });

Is really a bad idea. There are better ways to do it. And that is why you are facing problem sharing. Following method will work, and please make a NOTE that my solution is just to get you started on how you can do such a thing, to make it secure, you might have to restructure your angularjs app, and do what I am doing but inside a ng-service or ng-factory and inject the same in your controllers. This way you'll be able to access it.

Consider following.

app.js

    var express = require('express');
    var path = require('path');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');

    var routes = require('./routes/index');

    var app = express();

    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'hbs');

    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cookieParser());
    //This is very important, serve all your static files through public folder
    //Just inject your session variables to index.html, DO NOT PUT index.html
    //In you public folder, instead use index.hbs view as shown 

    app.use(express.static(path.join(__dirname, 'public')));

    app.use('/', routes);


    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
      var err = new Error('Not Found');
      err.status = 404;
      next(err);
    });

    // error handlers

    // development error handler
    // will print stacktrace
    if (app.get('env') === 'development') {
      app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
          message: err.message,
          error: err
        });
      });
    }

    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) {
      res.status(err.status || 500);
      res.render('error', {
        message: err.message,
        error: {}
      });
    });


    module.exports = app;

./routes/index.js

    var express = require('express');
    var router = express.Router();

    /* GET home page. */
    router.get('/', function(req, res, next) {
      res.render('index', {
        title: 'Pass session vairabled to my hbs',
        isAuthenticated: true,
        user: JSON.stringify({id: 2, name: 'dummy'})
      });
    });

    module.exports = router;

./views/layout.hbs

    <!DOCTYPE html>
    <html>
      <head>
        <title>{{title}}</title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
      </head>
      <body>
        {{{body}}}

        <!-- References of Angular.js and all your other angular files and services go here -->
        <script>
           var isAuthenticated= {{isAuthenticated}};
           var user = {{{user}}};
        </script>
      </body>
    </html>

./views/index.hbs

    <h1>{{title}}</h1>

    <div class="main" ng-view>
    </div>

Following is snapshot -- Proof of concept.

enter image description here

Now here I have just injected your variables in plain public js variables, you'll need to write ng-service/ng-factory to encapsulate.

Following is structure that i'd suggest

    .
    ├── LICENSE
    ├── README.md
    ├── app.js
    ├── bin
    │   └── www
    ├── package.json
    ├── public
    │   ├── images
    │   ├── javascripts
    │   ├── views
    │   │   └── <angular view templates>
    │   └── stylesheets
    │       └── style.css
    ├── routes
    │   └── index.js
    │   
    └── views
        ├── error.hbs
        ├── index.hbs //Your actual index file, this will contain ng-view
        └── layout.hbs

Hope this helps!! Please let me know if I can be of any further assistance.

Upvotes: 3

Related Questions