Recently, I was refactoring some Jade views of an ExpressJS application which shared significant JavaScript code. The JavaScript part required some variables from the server. Generally, this can be done like this:
script(type='text/javascript').
var user = !{JSON.stringify(userObject)};
Previously, the project had the following structure for many Jade views:
// some HTML view stuff
// ...
// and at the bottom the javascript
script(type='text/javascript').
// make user object accessible for javascript
var user = !{JSON.stringify(userObject)};
// some extensive Javascript code
// for demonstration purposes simplified:
alert('Hello ' + user.firstname);
The same Javascript code existed in multiple locations and was thus fairly bad style. In order to improve the situation I extracted the JavaScript code into a separated file, which I included in all Jade views.
My First (Broken) Approach
Jade view:
script(src="/js/user-functions.js")
And user-functions.js
:
// make user object accessible for javascript
var user = !{JSON.stringify(userObject)};
// some extensive Javascript code
// for demonstration purposes simplified:
alert('Hello ' + user.firstname);
Unfortunately, this did not work. The JSON.stringify()
method cannot be used, because the userObject does not exist in the context of the included JavaScript. In order to make the server-side variable available, you'll need to split the task between the Jade view and the included JavaScript. The jade view parses the object, the JavaScript file then can use that object.
Working Solution
The new Jade view:
script(type='text/javascript').
// make user object accessible for javascript
var user = !{JSON.stringify(userObject)};
script(src="/js/user-functions.js")
And user-functions.js:
// some extensive Javascript code
// for demonstration purposes simplified:
alert('Hello ' + user.firstname);
In this solution, I create a variable with the JSON.stringify()
method directly in the Jade view. That variable is available to all included scripts. Using this method you can clean up your project by separating between your views and your JavaScript code.