Example 2: MVC App
Like other famous development languages, such as .NET and Java, node.js does have development framework like MVC. This example will show you how to buildup a small MVC web application using express framework. Please note that this example is based on express version 4.13.4 .
Let’s create the folders:
example | under {your_node.js_installed_path}\nodejs\ |
demo2 | under {your_node.js_installed_path}\nodejs\examples\ |
app | under {your_node.js_installed_path}\nodejs\examples\demo2\app\ |
controllers | under {your_node.js_installed_path}\nodejs\examples\demo2\app\controllers\ |
models | under {your_node.js_installed_path}\nodejs\examples\demo2\app\models\ |
views | under {your_node.js_installed_path}\nodejs\examples\demo2\app\views\ |
include | under {your_node.js_installed_path}\nodejs\examples\demo2\app\views\include\ |
customer | under {your_node.js_installed_path}\nodejs\examples\demo2\app\views\customer\ |
product | under {your_node.js_installed_path}\nodejs\examples\demo2\app\views\product\ |
shop | under {your_node.js_installed_path}\nodejs\examples\demo2\app\views\shop\ |
config | under {your_node.js_installed_path}\nodejs\examples\demo2\config\ |
log | under {your_node.js_installed_path}\nodejs\examples\demo2\log\ |
public | under {your_node.js_installed_path}\nodejs\examples\demo2\public\ |
css | under {your_node.js_installed_path}\nodejs\examples\demo2\public\css\ |
img | under {your_node.js_installed_path}\nodejs\examples\demo2\public\img\ |
js | under {your_node.js_installed_path}\nodejs\examples\demo2\public\js\ |
Then, create a js file “app.js” under {your_node.js_installed_path}\nodejs\examples\demo2\ with below codes. It is entry point of demo2 application, and sets the global configures here.
//Declare required library
var express = require(‘express’); var bodyParser = require(‘body-parser’); var path = require(‘path’); var fs = require(‘fs’); var morgan = require(‘morgan’); var FileStreamRotator = require(‘file-stream-rotator’); var db = require(‘./config/db’);
var app = express(); var logFolder = __dirname + ‘/log’;
fs.existsSync(logFolder) || fs.mkdirSync(logFolder);
//Logger details var logFileStream = FileStreamRotator.getStream({ date_format: ‘YYYY-MM-DD’, filename: logFolder + ‘/demo2_%DATE%.log’, frequency: ‘daily’, verbose: false });
//Setup app variables app.set(‘port’, 3000); app.set(‘views’, __dirname + ‘/app/views’); app.set(‘view engine’, ‘ejs’);
app.use(morgan(‘combined’, {stream: logFileStream})); app.use(express.static( path.join(__dirname, ‘/public’))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true }));
//Setup the routes app.use(require(‘./app/controllers’));
//Setup Listener with Port app.get(‘port’) app.listen(app.get(‘port’), function () { console.log(‘Demo 2 listening on port ‘ + app.get(‘port’)); }); |
Under {your_node.js_installed_path}\nodejs\examples\demo2\config\ , please create the database configuration file db.js as below:
//Declare MySQL library
var mysql = require(‘mysql’); //Declare MySQL connection pool var pool = mysql.createPool({ host: ‘localhost’, user: ‘root’, password: ‘root’, database: ‘itblogs’, port: 3306 });
//Running select SQL exports.runQuery = function(query,callback) { //Making Query pool.getConnection(function(err, connection){ connection.query( query, function(err, rows){ if(err) { throw err; }else{ console.log( query ); callback(rows); } }); connection.release(); }); };
//Running insert,update,delete SQL exports.runSQL = function(sql,callback) { //Making Query pool.getConnection(function(err, connection){ connection.query( sql, function(err){ if(err) { console.log( sql + ‘ ::: ‘ + err ); callback(false); }else{ console.log( sql ); callback(true); } }); connection.release(); }); }; |
Please note that you may need to update the MySQL database connection username and password for your MySQL server:
var conn = mysql.createConnection({
host: ‘localhost’,
user: ‘root’,
password: ‘root’,
database: ‘itblogs’,
port: 3306
});
Let’s copy the below files to the related folders for front-end look and feel:
a. CSS ({your_node.js_installed_path}\nodejs\examples\demo2\public\css\). It is the CSS style for the front-end.
.listControls { }
.listControls md-divider { margin-top: 10px; margin-bottom: 10px; } .listControls md-list-item > p, .listControls md-list-item > .md-list-item-inner > p, .listControls md-list-item .md-list-item-inner > p, .listControls md-list-item .md-list-item-inner > .md-list-item-inner > p { -webkit-user-select: none; /* Chrome all / Safari all */ -moz-user-select: none; /* Firefox all */ -ms-user-select: none; /* IE 10+ */ user-select: none; /* Likely future */ } .listControls .secondary-button-padding p { padding-right: 100px; }
.listControls md-list-item > .md-button { width: 130px; }
.ng-table select { width: 80px; padding: 0px 3px; } |
b. JS ({your_node.js_installed_path}\nodejs\examples\demo2\public\css\). You can find the AngularJS for front-end here.
angular
.module(‘AngularApp’, [‘ngMaterial’, ‘ngTable’, ‘ngMessages’])
.controller(‘AppController’, function ($scope, $log) { $log.debug(“App start…”); })
.controller(‘HeaderController’, function ($scope, $timeout, $mdSidenav, $log) { $scope.toggleLeft = buildDelayedToggler(‘leftMenu’); /** * Supplies a function that will continue to operate until the * time is up. */ $scope.triggerMenu = function () { $mdSidenav(‘leftMenu’).toggle() .then(function () { $log.debug(“toggle Menu is done”); }); };
function debounce(func, wait, context) { var timer; return function debounced() { var context = $scope, args = Array.prototype.slice.call(arguments); $timeout.cancel(timer); timer = $timeout(function() { timer = undefined; func.apply(context, args); }, wait || 10); }; } /** * Build handler to open/close a SideNav; when animation finishes * report completion in console */ function buildDelayedToggler(navID) { return debounce(function() { $mdSidenav(navID) .toggle() .then(function () { $log.debug(“toggle ” + navID + ” is done”); }); }, 200); } function buildToggler(navID) { return function() { $mdSidenav(navID) .toggle() .then(function () { $log.debug(“toggle ” + navID + ” is done”); }); } } })
.controller(‘MenuController’, function ($scope, $mdSidenav, $window, $log) { $scope.close = function () { $mdSidenav(‘leftMenu’).close() .then(function () { $log.debug(“close leftMenu is done”); }); }; $scope.goURL = function ( url ) { $window.location.href = url; }; })
.controller(‘TableController’, function($scope, NgTableParams){ var self = this; self.tableParams = new NgTableParams({ count: 5}, { counts: [5, 10, 25], dataset: data});
$scope.getStatus = function(data) { return [{id:”1″, title:”1″}, {id:”0″, title:”0″}]; }; })
.controller(‘FormController’, function($scope){ $scope.record = { }; }); |
c. img ({your_node.js_installed_path}\nodejs\examples\demo2\public\img\). Storing image files here. Please download here.
As this example will demonstrate MVC framework, let’s create the framework layer by layer.
A. Controllers
Download here and store the codes under {your_node.js_installed_path}\nodejs\examples\demo2\app\controllers\
You can find the business logic in this layer
B. Models
Download here and store the codes under {your_node.js_installed_path}\nodejs\examples\demo2\app\models\
You can find the models here.
C. Views
Download here and store the codes under {your_node.js_installed_path}\nodejs\examples\demo2\app\views\. You can find the ejs templates here. You may need to update these templates if you want to change the look and feel.
Ok, everything is ready now. Let’s try to run the application and see what’s happening. You can:
- run “cmd”
- cd {your_node.js_installed_path}\nodejs\
- node examples/demo2/app.js
Then, open with a browser (http://localhost:3000), you should find the below page.
You can find the menu on the top left hand side , it will show you a menu when clicking on it.
Done, let’s try to play with it. Happy Node.js day.
However, if you still remember, this blog has mentioned that Node.js is not good for CRUD application like this example. It is suggested to develop Node.js restful API for the backend, and called by AngularJS of the frontend, like the next example: Restful API.