Show all of data comming from mongodb and render it in doT.js templating engine

I wanted to extract data from mongodb and pass it to the view. Everything seems to work, but instead of seeing all 10000 records show up I see only one. I feel that I am very close to solving it, but I got stuck... I am using node-mongodb-native, express and dot.js to achieve my goal.

Here is my app.js, look for the app.get() that's where all the action is:

    /**
 * Mongo DB
 */
var mongodb = require('mongodb'),
    serverdb = new mongodb.Server('127.0.0.1', 27017, {}),
    dbName = new mongodb.Db('test', serverdb, {});
/**
 * Module dependencies.
 */
var express = require('express'),
    doT = require('doT'),
    app = express.createServer(),
    pub = __dirname + '/public',
    view =  __dirname + '/views';

// Configuration
app.configure(function(){
    app.set('views', view);
    app.set('view options', {layout: false});
    app.set('view engine', 'html');
    app.use(app.router);
});

//Simple templating
app.register('.html',doT, {
    compile: function(str, opts){
        return function(locals){
            return str;
        }
    }
});


//----------------- This is where the problem is i think ---------------
app.get('/', function(req, res){
    dbName.open(function (error, client) {
        var collection = new mongodb.Collection(client, 'personnel');
        collection.find().each(function(err, data){
            //Error check
             if (err){return res.end('error!'+err);}
            //Data
             if (data){
                res.render('index.html',{data:data._id});
             } else {
                 res.end();
             }
        });
    });
});
//--------------------------------------------------------------


app.configure('production', function(){
    app.use(express.errorHandler());
});
app.listen(3000);
console.log('Express server listening on port %d in %s mode', app.address().port, app.settings.env);

And here is my html:

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Index</title>
</head>
<body>
    {{=it.data}}
</body>
</html>

Please help if you can. Thank you.

Answers:

Answer

I don't know anything about dot.js templating engine. But I would guess that your call to res.render('index.html',{data:data._id}); results in the page being re-rendered for each element in the cursor and you end up with the last rendering of the page.

Answer

While iterating, you can store each data into an array or linkedlist. After finish iterating the array, you can res.render and pass the array or linkedlist into the view.

Answer

Well, I finally found a solution, first I had to change from each() to toArray() where retrieves my data is retrieved. then I stringify-ed my data. It's not an ideal solution, since I just print out everything as one string as opposed to iterating through the data in the template. I am just glad I am moving in the right direction.

My app.js:

EDIT: found even better solution.

    //Replace this code with the one in my question to get full file
    //----------------- This is where the problem was ---------------
    app.get('/', function (req, res) {
        dbName.open(function (error, client) {
            var collection = new mongodb.Collection(client, 'some_collection');
            collection.find().limit(300).toArray(function (err, dataObjArr) {
                var data = '';
                var dataArr = [];
                var i = dataObjArr.length;
                //check for error
                if(err){return res.end('error!'+err);}
                //Data
                if (dataObjArr) {
                    while(i--){
                        dataArr[i] = dataObjArr[i]._id;
                    }
                    data = dataArr.join(' ');
                    res.render('index.html', { returnedData : data });
                }else{
                    res.end();
                }
            });
        });
    });
    //--------------------------------------------------------------

my index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Index</title>
</head>
<body>
    {{=it.returnedData}}
</body>
</html>

Like I said, it's not ideal solution, but I think now I have to put advanced features of the templating engine itself to work.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.