3

I'm brand new to the MEAN stack and I am trying to figure out the best way to handle my routing, either express.Router() or AngularJS's controllers (https://docs.angularjs.org/tutorial/step_07).

I am using Express v4.12.0, Angular v1.3.13, EJS v1 (for templating).

I really like how clean the URLs are from Express's routing (/items/itemId) and I'm not too fond of Angular's, since it uses hashs in the URL (/items#/items/itemId).

Right now I have a single page that lists my items (players.ejs):

<!DOCTYPE html>
<html lang="en" ng-app='app'>
<head>
    <title>Fantasy Football Helper | <%- title %></title>
    <% include partials/head %>
    <script type="text/javascript" src="/javascript/app/playersApp.js"></script>
</head>
<body class="container">

    <% include partials/header %>

    <main>
        <div class="row">
            <div class="col-sm-8">

                <h2>Fantasy Players</h2>

                <div ng-controller="PlayerController">
                    <div class="player" ng-repeat="player in players">
                        <p>
                            <a href="/players/{{ player._id }}"><strong>{{ player.name }} - {{ player.position }} - {{ player.team }}</strong></a>
                        </p>
                    </div>
                </div>
                <!-- Ideally, other CRUD UI goes here -->

            </div>

            <% include partials/sidebar %>
        </div>
    </main>

    <footer>
        <% include partials/footer %>
    </footer>

</body>
</html>

I would like to reuse this players.ejs template for each of my CRUD operations for these players. Currently I am using Express's routing. I have the following route in my main app.js:

var players = require('./routes/players');
app.use('/players', players);

And I have the following routes inside of the players route (routes/players.js):

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

/* GET /players listing. */
router.get('/', function(req, res, next) {
    res.render('players', { title: 'Players'});
});

/* GET /player details. */
router.get('/:id', function(req, res, next) {
    res.render('players', { title: 'Fantasy Players'});
});

module.exports = router;

Is there a way, using Express's routing, to have a single EJS template that serves up different partials depending on the http operation?

Note: I've been referencing the following guides:

Fillip Peyton
  • 3,637
  • 2
  • 32
  • 60

2 Answers2

3

You can pass a boolean to your template:

router.get('/', function(req, res, next) {
    res.render('players', { title: 'Players', foo: true});
});

router.get('/:id', function(req, res, next) {
    res.render('players', { title: 'Fantasy Players', foo: false});
});

And render a different partial depending on the boolean:

<%if (foo) { %>
 <% include partials/foo %>
<% } else { %>
  <% include partials/bar %>
<% } %>
Miguel Mota
  • 20,135
  • 5
  • 45
  • 64
2

I'm sure there are many ways and approaches to this. I can tell you what worked for me, a method I've adopted from pluralsight.

Let your express routes all serve up the same index.ejs file:

app.get('/', function(req, res, next) {  
 res.render('index.ejs',{
   page: 'home'
 });
}); 

app.get('/about', function(req, res, next) {  
 res.render('index.ejs',{
       page: 'about'
     });
    }); 

app.get('/about/:id', function(req, res, next) {
 res.render('index.ejs',{
       page: 'about'
     });
    }); 

My index.ejs is stripped down for the most part with the navigation ng-view and footer.

My express routes handle all of the server logic on http requests:

router.get('/abo', aboutController.list);
router.post('/abo', aboutController.create);
router.route('/abo/:_id')
    .get(function(req, res) {
        About.findById(req.params._id, function(err, result) {
            if (err)
                res.send(err);
            res.json(result);
        });
    })
.put(function(req, res) {
        About.findById(req.params._id, function(err, abo) {
            if (err)
                res.send(err);
            abo.title = req.body.title;     // update the items info
            abo.shortname = req.body.shortname;
            abo.contents = req.body.contents;
            // save the items
            abo.save(function(err) {
                if (err)
                    res.send(err);
                res.json({ message: 'About content updated!' });
            });
        });
    })
.delete(function(req, res) {
        About.remove({
            _id: req.params._id
        }, function(err, service) {
            if (err)
                res.send(err);

            res.json({ message: 'Successfully deleted' });
        });
    });

Angular matches the express url routes:

.when('/', {
        templateUrl: 'templates/home.html',
        controller:'homeController'

    })
.when('/about/:id', {
        templateUrl: 'templates/template.html',
        controller: 'refactoredController'
    })

I'm also using:

$locationProvider.html5Mode(true);

Which allows for clean urls without the #

My angular controllers talk to the angular service I have set up for http calls, which pass the data along to the backend(express), where the routes take over.

function getByID(shortname, api) { 
return $http({
  method: 'GET',
  url: '/api/' + api,
  shortname: shortname
})
.then(getVolunteerByIDSuccess)
.catch(sendGetVolunteerError);

} 

function updateItem(data, api) {
  console.log(data);
  return $http({
    method: 'PUT',
    url: 'api/'+ api + "/" + data._id,
    data: data  
  })
  .then(updateItemSuccess, data)
  .catch(updateItemError);
}


function addItem(newItem, api){
  return $http({
    method: 'POST',
    url: 'api/' + api,
    data: newItem  
  })
  .then(updateItemSuccess, newItem)
  .catch(updateItemError);
}

function deleteItem(data, api){
  var titleDeleted = data.title;
  return $http({
    method: 'DELETE',
    url: 'api/'+ api + "/" + data._id,
    titleDeleted: titleDeleted
  })
  .then(updateItemSuccess, titleDeleted)
  .catch(updateItemError);
}  

It's a lot to go over, but hopefully that gives you an idea. These are all just small parts of the code. I picked up the info from all different sources for mean stack, but have refactored everything mostly based on pluralsight's courses.

byrdr
  • 5,197
  • 12
  • 48
  • 78