Reputation: 307
I come from a very "functional" style of programming (PHP, Lua, C) and I'm trying to transition my thinking to the MVC model NodeJS uses. Currently, this is a very steep learning curve for me.
I've been banging my head against the wall trying to get a simple MySQL array to print out to Jade.
app.js
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, mysql = require('mysql');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
//MySQL
var sqlInfo = {
host: '12.34.56.78',
user: 'user',
password: 'pass',
database: 'user'
}
var client = mysql.createConnection(sqlInfo);
client.connect();
client.query( "SELECT * FROM list ORDER BY status ASC LIMIT 25", function(err, row, fields){
if (err) throw err;
else {
var applications = row;
app.render("applications", applications, function(err, html){});
}
});
client.end();
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
index.jade
extends layout
block content
div.container
div.content
- if (typeof(applications) !== 'undefined')
ul
- each app in data
li= app.status
- else
p Blank slate mate...
div.footer
I think my issue is stemming from the app.render/res.render function... The concept of this function is not really clicking and I'm having problems getting it to work like I've seen in so many other MySQL + NodeJS examples.
Any tips or hints are much appreciated!
Upvotes: 3
Views: 7627
Reputation: 203359
The problem is that you're trying to render a query outside the HTTP flow. That could be your intention (in which case I'm interested in hearing what exactly you're trying to do with the rendered result), but usually, you wait for an HTTP request before you return the results of your query.
For example:
app.get('/test', function(req, res) {
// connect to MySQL server
var client = mysql.createConnection(sqlInfo);
client.connect();
// Perform query and wait for results
client.query( "SELECT * FROM list ORDER BY status ASC LIMIT 25", function(err, row, fields) {
// Done with the connection
client.end();
// Handle error
if (err) throw err;
else {
// We got a result: render it
var applications = row;
res.render("applications", { applications : applications });
}
});
});
A few pointers:
http://localhost:PORT/test
client.end()
right after client.query()
, but without waiting for the query to return any results. So I moved client.end()
to inside the code which handles the query result, to make sure the connection is ended only after the results are returned;data
, but I think that should be applications
;Upvotes: 5
Reputation: 2294
I can see two issues here.
First, you pass"applications"
as the first parameter to app.render(). This should probably be "index"
to match your view name.
Second, and this is the key point I think you're missing, is that you need to do something with html
in the function you pass to app.render().
app.render("applications", applications, function(err, html){
//see what you have for html here
});
The idea behind passing a function in to render is it works like a callback. You can inspect err to see if there was a problem with rendering the view. If there was no error, html
should have the rendered HTML based on the Jade template and whatever data you passed in (applications
).
If you still have a problem, I have a couple suggestions. You should probably debug your data to see what that looks like. Make sure the MySQL query returns data in a format your expecting. Then you can see if your template works. Try passing in a simple data object and use a simple Jade template at first to make sure you're calling app.render() correctly.
I hope that helps!
Upvotes: 1
Reputation: 48003
You can pass variables to the jade when rendering view like this:
res.render('index', { applications: applications }, function(err, html){});
Then you can use it inside your index.jade:
if (typeof(applications) !== 'undefined')
Upvotes: 1