Crystal Wesnoski Crystal Wesnoski - 11 days ago 11
Node.js Question

Passing in data from Mongodb to HTML table using javascript using Node.js framework

I'm quite new at using node.js. Right now I'm trying to pull data from MongoDB and display it in a table using Javascript + HTML. However, my table is populating with undefined in all the fields. I think something is definitely wrong with how I'm reading data through to the Javascript function b/c I am able to render the full results from the people.js file straight to the webpage. Thank you in advance!! Below is my code:

Code for my people.js file:

exports.getPeople = (req, res) => {
People.find((err, docs) => {
if (err) { return next(err); }
if (docs != null){
docs.forEach(function(docs, index) {
console.log(index + " key: " +
res.render('people', { people: docs });
res.render('people', { people: docs() });

My Javascript + HTML that's populating my webpage.

script(type='text/javascript', src='', charset='UTF-8')
var obj= '$(people)'

var tbl = "<table>"
var content="";
for(i=0; i<obj.length;i++){
content +=
'<tr>+<td>' +obj[i]["name"]+
'</td><td>'+ '<input type="button" value = "Update" onClick="Javacsript:deleteRow(this)">' +
'</td><td>'+'<input type="button" value = "Delete" onClick="Javacsript:deleteRow(this)">';
content += "</table>"


As you mentioned, you can render the array results from the people.js file directly into the webpage. So, you don't have to read the data through a JavaScript function using jQuery. The template engine language is built on top of JavaScript and it supports plenty of methods and features to do what you're trying to achieve here. So, for example, you may use an iteration method like to build your table (see docs - Iteration):

// ...


        // for each person in the people array (from people.js) ...

        each person in people 

          // build a new table row

            // insert table data
            td #{}
            td #{person.type}
            td #{person.min_hours}
            td #{person.max_hours}
            td #{}
            td #{person.phone_number}

            // add the update and delete buttons
              input(type="button" value = "Update" onclick=" ... ")
              input(type="button" value = "Delete" onclick=" ... ")

            // move to next person in the people array ...

The Problem

var obj = '$(people)' does not work as you may expect. You want obj to hold the people array from the people.js file so that you can loop over each object in the array, but this is not what's happening. obj is actually a string value of length 9, so the for loop evaluates 9 string values (not objects). This is why all of your fields are undefined.

To see what I mean, run this code snippet:

var obj = '$(people)';

for (var i = 0; i < obj.length; i++){


The reason $(people) does not evaluate to an object is mainly because the parent element, script. causes everything below it to evaluate to plain text. The . after the tag causes the template engine to render plain text (see docs: Block in a Tag).

If you wanted to assign people to obj in your inline script you may try it this way:

  | var obj = #{people};

But this will cause an Unexpected identifier JavaScript error because of the _id field on each item in people. By default _id is an ObjectID hex value from MongoDb so you would have to either remove the _id field from the docs or add quotes to each doc._id so it evaluates to a string. This would all have to be done in person.js before you return the data.

To see what I mean about the Unexpected identifier error, run this code snippet:

// works
var obj = { _id: '583ab33cdaf857b543c76afe',
  name: 'john'};

// Error: Unexpected identifier
var obj = { _id: 583ab33cdaf857b543c76afe,
  name: 'john'};