title: How to render data using Express 4 + Pug/Jade + Angularjs
body: <p>I'm starting learning Express and Angularjs. In the project, I want to render HTML at the server side and bind data via Angularjs but it didnt work. I saw that ng-repeat is disable in browser</p>
  
  <pre><code>&lt;body ng-app="photoApp" class="ng-scope"&gt;
    &lt;h1&gt;Express&lt;/h1&gt;
    &lt;p&gt;Welcome to Express&lt;/p&gt;
    &lt;!-- ngView: --&gt;
    &lt;div ng-view="" class="ng-scope"&gt;
      &lt;div id="photos" class="ng-scope"&gt;
        &lt;!-- ngRepeat: photo in vm.photos --&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>, therefore no data is showed. Please help me to fix that, thanks in advanced!</p>
  
  <p>Project Structure</p>
  
  <pre><code>photo
  --public
  ----javascript
  ------lib
  ------photoApp.js
  --routes
  ----index.js
  ----photo.js
  --views
  ----partials
  ------photo-list.pug
  ----error.pug
  ----index.pug
  ----layout.pug
  --app.js
  </code></pre>
  
  <p><strong>Server-side code:</strong></p>
  
  <p>app.js</p>
  
  <pre><code>var express = require('express');
  var path = require('path');
  var favicon = require('serve-favicon');
  var logger = require('morgan');
  var cookieParser = require('cookie-parser');
  var bodyParser = require('body-parser');
  
  var routes = require('./routes/index');
  var users = require('./routes/users');
  var photos = require('./routes/photos');
  
  var app = express();
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'pug');
  
  // uncomment after placing your favicon in /public
  //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
  app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(cookieParser());
  app.use(express.static(path.join(__dirname, 'public')));
  
  app.use('/', routes);
  app.use('/users', users);
  app.use('/photos', photos);
  
  // 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;
  </code></pre>
  
  <p>index.js</p>
  
  <pre><code>var express = require('express');
  var router = express.Router();
  
  /* GET home page. */
  router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
  });
  
  router.get('/partials/:name', function(req, res, next){
      var name = req.params.name;
      res.render('partials/' + name);
  });
  
  module.exports = router;
  </code></pre>
  
  <p>photos.js</p>
  
  <pre><code>var express = require('express');
  var router = express.Router();
  
  var photos = [];
  photos.push({
    name: 'Node.js Logo',
    path: 'http://nodejs.org/images/logos/nodejs-green.png'
  });
  photos.push({
    name: 'Ryan Speaking',
    path: 'http://nodejs.org/images/ryan-speaker.jpg'
  });
  
  router.get('/api/get-all', function(req, res) {
      res.json(photos);
  });
  
  router.get('/', function(req, res) {
      res.render('photos');
  });
  
  module.exports = router;
  </code></pre>
  
  <p>layout.pug</p>
  
  <pre><code>doctype html
  html
      head
          title= title
          link(rel='stylesheet', href='/stylesheets/style.css')
          script(src='javascripts/lib/angular.js')
          script(src='javascripts/lib/angular-route.js')
          script(src='javascripts/photoApp.js')
      body(ng-app="photoApp")
          block content
  </code></pre>
  
  <p>index.pug</p>
  
  <pre><code>extends layout
  
  block content
    h1= title
    p Welcome to #{title}
    div(ng-view)
  </code></pre>
  
  <p>photo-list.pug</p>
  
  <pre><code>#photos
      .photos(ng-repeat="photo in vm.photos")
          h2 {{photo.name}}
          img(src="{{photo.path}}")
  </code></pre>
  
  <p>Client-side code:</p>
  
  <p>photoApp.js</p>
  
  <pre><code>var photoApp = angular.module('photoApp', ['ngRoute']);
  photoApp.controller('PhotoListController', PhotoListController);
  photoApp.config(['$routeProvider', function($routeProvider){
      $routeProvider
          .when('/', {
              templateUrl: 'partials/photo-list',
              controller: 'PhotoListController',
              controllerAs: 'vm'
          })
          .otherwise({
              redirectTo: '/'
          });
  }]);
  
  function PhotoListController($scope, $http) {
      var vm = this;
      vm.getAllPhotos = getAllPhotos; 
  
      function getAllPhotos(){
          $http.get('/photos/api/get-all')
              .success(function(response) { vm.photos = response.photos; })
              .error(function() { console.log('Error when getting all photos'); });
      }
  }
  </code></pre>