Nic Meiring
Nic Meiring

Reputation: 882

rendering jade files in expressjs

I have a basic expressjs app (using jade), but I am having trouble rendering basic Jade files. When I get a request, i parse the url for the pathname and use the handle object to route the request as follows:

index.js

var requestHandlers = require('./requestHandlers');

var handle = {};
handle['/'] = requestHandlers.start;
handle['/download'] = requestHandlers.download

requestHandlers.js

   function start(res) {
        console.log("request handler for start called");
        res.render('home', {title: 'express'});
    }

    function download(res) {
        res.render('download', {title: 'download'})
        res.end();
    }

    exports.start = start;
    exports.download = download;

home.jade

h1= title
p Welcome to #{title}

I am using Jade as my templating engine, and have configured the server in a seperate server.js file. When i request either of the pages, the title displays correctly on my browser tab, but the page doesn't display, it just keeps loading. Weirdly, when I cancel the request the page displays. It's as if everything works but nothing tells the process to end?

I am relatively new to node so excuse my naiveté on any of the above. Let me know if there are any questions I can clear up.

Upvotes: 1

Views: 6246

Answers (1)

Ankit Aggarwal
Ankit Aggarwal

Reputation: 1546

I'm not 100% positive why your code isn't killing the TCP connection as needed to prevent your browser from timing out, but I can provide a solution that is friendly towards Express conventions that should solve your issues and maintain code readability, maintainability, and separation.

./app.js (your main server script)

var express = require('express'),
    app = express.createServer(),
    routes = require('./routes');

app.configure(function () {

    // Render .jade files found in the ./views folder
    // I believe you are already doing this
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');

    // Use the built-in Express router
    // This kills the "handle" method you had implemented
    app.use(app.router);

    // Client-side assets will be served from a separate ./public folder
    //     i.e. http://yourhost.com/js/main.js will link to ./public/js/main.js
    app.use(express.static(__dirname + '/public'));

});

// Initialize routes
routes.init(app);

./routes/index.js

exports.init = function (app) {

    app.get('/', function (req, res) {
        console.log("request handler for start called");

        // Render __dirname/views/home.jade
        res.render('home', {title: 'express'});
    });

    app.get('/download', function (req, res) {
        // Render __dirname/views/download.jade
        res.render('download', {title: 'download'})
    });

});

The above prevents you from needing to parse the URL parameters by yourself. Also you can define more readable and powerful request handlers (i.e. app.post for POST methods). You are now enabled to more easily tie in things like the Express-Resource module if you decide to build a REST API.

If you need more powerful mappings you can use regular expressions in the first parameter of app.[get/post/put/del] to filter for specific paths instead.

Upvotes: 3

Related Questions