添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a node.js server written in express and at a certain moment I send to some .jade page an array. The problem is that when rendering the Jade page, the Jade compiler renders the array as [object Object] and the JavaScript compiler on Chrome complains about it saying "Unexpected identifier".

This is the Jade code:

!!! 5
html(lang="en")
    title= "Rankings"
        h1 Ranking
        div(id="rankings")
    script(type='text/javascript')
        function fillRanking(){
            var rankArray = #{ranking};
            alert("inside fillranking");
            var divElement = document.getElementById("rankings");
            for(var i = 0; i< rankArray.length; i++){
                divElements.innerHTML += "" + i+1 + ". " + rankArray[i].Username + " " + rankArray[i].Points;
        fillRanking();

As you can see it's really simple, I just fill a div with the info given by what's inside the #{ranking} variable passed by node.js to Jade. The alert on the second line doesn't fire because the Unexpected Identifier error happens as soon as I try to assign the #{ranking} variable.

The following is the code in my node.js with express

app.get('/ranking', function (req, res) {
    //get the first ten people in the ranking
    var firstTen = getRanking(10, function(results){
        //compute the array of results
        var result = {
            ranking: [],
        for(var i = 0; i < results.length; i++){
            result.ranking[i] = results[i];
        //render the ranking with all the info
        console.log(result);
        res.render(__dirname + '/pages/ranking/ranking.jade', {
            ranking: result,

I create an object with inside an array of results, I put the results I found out of the query inside it and I pass it to the rendering engine. The console.log(results) call prints the result object correctly, for example like this:

{ ranking: 
   [ { Username: 'usr1',
       _id: 4ed27319c1d767f70e000002,
       Points: 100 },
     { Username: 'usr2',
       _id: 4ed27326c1d767f70e000003,
       Points: 100 } ] 

I don't really know how to handle the variable passed to the Jade page. Whichever thing I do I keep getting the "Unexpected identifier" error. Does anyone of you know how do I solve this?

Thanks

Any reason you don't have jade iterate over the array and build the list as part of the template? Search "Iteration" at github.com/visionmedia/jade. – Ryan Olds Nov 28, 2011 at 8:52 Well, it's another way of seeing things. I got what you mean, but can you please provide an example of what you said as a response to this question? I would like to see how would you do it without incurring into the "Unexpected identifier" error. Thanks – Masiar Nov 28, 2011 at 9:18 Could try {ranking: JSON.stringify(result)}. To be clear, this is not optimal. Building the list as part of template with using Jade's 'Iteration' functionality completely avoids the need for the browser to execute JavaScript for this. – Ryan Olds Nov 28, 2011 at 9:28 Doing this var rankArray = JSON.stringify(#{ranking}); gives again Unexpected identifier error. Same happens with var rankArray = {ranking: JSON.stringify(#{ranking})};. I still don't see how building the list directly in HTML would avoid the JavaScript error I get, since every time JS tries to evaluate #{ranking} it fires the error. – Masiar Nov 28, 2011 at 9:43

Looking at the comments above and investigating a little bit more, here's what I've found to work:

Use this on your javascript (/controller):

res.render(__dirname + '/pages/ranking/ranking.jade', { ranking: JSON.stringify(ranking),

And on jade template:

function fillRanking(){ var rankArray = !{ranking}; alert("inside fillranking");

This works because !{} doesn't perform escaping.

Before you do this, make sure that ranking doesn't contain any unescaped user-controllable strings: escape.alf.nu/2 – James Feb 17, 2014 at 9:17

This works for me.

JSON.stringify the array (or any arbitrary JSON object really) on the server and then JSON.parse it on the client.

server-side:

res.render(__dirname + '/pages/ranking/ranking.jade', {
    ranking: JSON.stringify(result),

client-side:

var rankArray = JSON.parse( !{JSON.stringify(ranking)} );

Because I also use the array from the controller for iteration, I did this:

res.render('template', pArrayOfData);

And in the jade code:

script(type='text/javascript').
            var _histData = !{JSON.stringify(pArrayOfData)};

I encountered the same problem and was able make it work with a slight variation (thanks to the solutions above).

From my code:
Backend:

Stringify the JSON array

router.get('/', function(req, res) {
    var data = JSON.stringify(apiData);  // <====
    res.render('gallery', { data: apiData });

Frontend:

Stringify again with the !{}

    function injectDataOnView() {
        var data = !{JSON.stringify(data)}; // <====
        var divElement = document.getElementById('data');
        divElement.innerHTML = data[1]['id']; // <=== just a test, so no for loop
    injectDataOnView();
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.