[et_pb_section bb_built=”1″ fullwidth=”on” specialty=”off” _builder_version=”3.0.64″ next_background_color=”#000000″][et_pb_fullwidth_post_title admin_label=”Blog Post Header” _builder_version=”3.17.2″ title=”off” meta=”off” categories=”off” comments=”off” featured_placement=”background” text_orientation=”center” module_class=”blog_post_header” title_font_size=”60px” background_blend=”saturation” title_font=”Raleway|on|||” title_text_color=”#274060″ title_letter_spacing=”2px” meta_font=”Raleway||||” meta_font_size=”20″ meta_text_color=”#274060″ meta_letter_spacing=”2px” background_color=”rgba(144,144,144,0.39)” /][/et_pb_section][et_pb_section bb_built=”1″ _builder_version=”3.0.63″ prev_background_color=”#000000″][et_pb_row _builder_version=”3.0.63″][et_pb_column type=”4_4″][et_pb_text admin_label=”Blog Post” _builder_version=”3.17.2″ module_alignment=”left” text_font=”||||” header_font=”||||” max_width_tablet=”50px”]

Originally published: IBM Systems Magazine on 5/13/15
Author Notes: Jade has been renamed to Pug.

One of the primary uses of Node.js is for creating Web applications.

When it comes to popular Web frameworks for Node.js, Expressjs.com is at the top of the list. In this article, I’ll show how to get up and running quickly with a simple app that displays a listing of customers and explain the various technologies involved along the way.

First things first: Create a directory named nodejs_expressjs and cd into it, as shown:

$ mkdir nodejs_expressjs && cd nodejs_expressjs

You’ll notice two && characters in the middle. This allows me to enter two commands and have them execute in succession. I point this out because you’ll find this in Node.js documentation and I wanted to explain what it does.

Next, we need to use npm, Node Package Manager, to install the express package (aka “module”). Notice it will also download and install all the dependencies of express. This is a big timesaving feature as was discussed in my previous article.

$ npm install express
express@4.12.3 node_modules/express
├── merge-descriptors@1.0.0
├── utils-merge@1.0.0
├── cookie-signature@1.0.6
├── methods@1.1.1
├── range-parser@1.0.2
├── fresh@0.2.4
├── cookie@0.1.2
├── escape-html@1.0.1
├── content-type@1.0.1
├── parseurl@1.3.0
├── vary@1.0.0
├── finalhandler@0.3.4
├── serve-static@1.9.2
├── content-disposition@0.5.0
├── path-to-regexp@0.1.3
├── depd@1.0.1
├── on-finished@2.2.0 (ee-first@1.1.0)
├── qs@2.4.1
├── debug@2.1.3 (ms@0.7.0)
├── etag@1.5.1 (crc@3.2.1)
├── send@0.12.2 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
├── proxy-addr@1.0.7 (forwarded@0.1.0, ipaddr.js@0.1.9)
├── type-is@1.6.1 (media-typer@0.3.0, mime-types@2.0.10)
└── accepts@1.2.5 (negotiator@0.5.1, mime-types@2.0.10)

Now that ExpressJs is installed, we’re ready to start developing our Web application. Hello World is always a good place to start. Create a file named app.js and insert the following code into it:

---app.js---
var express = require('express')
var app = express()
app.get('/', function (req, res) {
  res.send('Hello World')
})
app.listen(8001)

The first line is bringing in the express framework and the second is gaining access to the app object (in the end what we need). Next, we see a call to app.get(...). This is saying “whenever an HTTP GET request is made for the site’s root, send the words ‘Hello World’ as the response.” The second parameter is an anonymous function that’s called upon to handle requests to the root of the site. The last line tells the application which port to listen on (in this case port 8001).

Now it’s time to start the application for the first time and see if it works.

You can start the app using the following syntax:

$ node app.js

You should see something like Figure 1 if it worked.

Our first working application.
Our first working application.

A next step of making this a legitimate application is to create a package.json file, which will store things like module dependencies, author, version, etc.—much like what the express module uses its package.json file for. To create a package.json file, we use the npm init command, as shown:

$ npm init

That command will prompt you for a number of values with an end goal of generating a package.json file similar to the following. Notice how it recognized that express was installed already in the node_modules/ folder.

{
  "name": "nodejs_expressjs",
  "version": "0.0.0",
  "description": "",
  "main": "app.js",
  "dependencies": {
    "express": "^4.12.3"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Introducing Jade

Next, we want to further develop our application by implementing a template engine to make creating dynamic HTML pages simpler. We’ll select the Jade template engine due to its popularity and flexibility. To install Jade, we will again go to the npm install command, except this time we’ll add a –save option at the end to declare we’d like this to be retained in the package.json file.

$ npm install jade --save
jade@1.9.2 node_modules/jade
├── character-parser@1.2.1
├── commander@2.6.0
├── void-elements@2.0.1
├── mkdirp@0.5.0 (minimist@0.0.8)
├── with@4.0.3 (acorn-globals@1.0.4, acorn@1.0.3)
├── constantinople@3.0.1 (acorn-globals@1.0.4)
└── transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)

Following we see the modified package.json file with reference to the Jade module.

{
  "name": "nodejs_expressjs",
  "version": "0.0.0",
  "description": "",
  "main": "app.js",
  "dependencies": {
    "express": "^4.12.3",
    "jade": "^1.9.2"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Next, we need to create a folder to hold our new template engine files so we can keep them separate and organized from the rest of the application. Run the following mkdir command to create a directory named views:

$ mkdir views

Within the views directory, create a file named index.jade and populate it with the following text, making sure to retain the leading spaces. What you see is Jade syntax that aims to make HTML composition significantly less “noisy” (i.e., more whitespace). Indentation in Jade allows us to declare when closing tags should be assumptively inserted. For example, the head tag will close when the body tag is encountered because they’re at the same indentation depth.

When you see an equal sign (=), or exclamation plus equal sign (!=), it means the content on the right is a variable made available to the view from the controller. There are many more aspects you can learn about in the Jade reference.

html
  head
    title!= title
  body
    h1!= message

Following are the necessary Jade additions for views to work in app.js. First, we use app.set() to declare the folder where views are stored and then set the view engine to ‘jade’. Once the view engine is set, we can alter the contents of app.get() to invoke res.render(), passing the name of the view (index) and set named variables we want to pass to the view—namely title and message.

app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
. . .
app.get('/', function (req, res) {
 res.render('index', { title: 'Hey', message: 'Hello there!'})
})
. . .

At this point, we’re ready to start the application again, with the following command. If your application is still running from last time, you’ll need to first end it (i.e., Ctrl + C) and start it again. Doing this will pick up the latest changes in app.js.

$ node app.js

More Dynamic

Now that we know how to pass variables to the view layer, let’s make it a bit more dynamic by retrieving database rows to display a list of customers from table QIWS.QCUSTCDT. This table ships with IBM i. To accomplish this, we’re first going to create a new file named customers.jade in the views directory and populate it with the following content.

Here we learn about Jade’s ability to iterate over a result set using the each keyword. The results variable was provided by the controller (app.js) and the row variable is occupied with an SQL row at each iteration. LSTNAM and CUSNUM are columns in DB2 table QCUSTCDT.

h1=title
  table
    thead
      tr
        th Last Name
        th Customer Number
    tbody
      - each row in results
        tr
          td=row.LSTNAM
          td=row.CUSNUM

Next, we need to make changes to app.js that query DB2 to provide the results variable to the customers.jade view, as shown. Note, only additions are being shown.

var db = require('/QOpenSys/QIBM/ProdData/Node/os400/db2i/lib/db2')
db.init()
db.conn("*LOCAL")
. . .
app.get('/customers', function (req, res) {
  db.exec("SELECT LSTNAM, CUSNUM FROM QIWS.QCUSTCDT", function(results) {
   res.render('customers', { title: 'Customers', results: results})
  })
})

Next, let’s introduce a feature of displaying more information about a customer when it’s clicked. We can do that by modifying the td tag holding the CUSNUM value to have a dynamically generated link to that specific customer, as shown. The #{...} syntax is string interpolation and makes referencing variables in strings significantly easier. Also note the indentation needs to be correct number of spaces.

         td: a(href='/customer/#{row.CUSNUM}')=row.CUSNUM

Now we need to add code to app.js to process requests for specific customers, as shown.

app.get('/customer/:id', function (req, res) {
  var sql = "SELECT * FROM QIWS.QCUSTCDT WHERE CUSNUM=" + req.params.id
  db.exec(sql, function(result) {
    res.render('customer', { title: 'Customer', result: result[0]})
  })
})

Note the :id reference in the first parameter of app.get(). This says that whatever is specified on the URL after /customer/ should be placed into a variable named id within the req.params array. We can then access it with the syntax req.params.id and concat it into the SQL statement. Then we use result[0] to set the result view variable.

NOTE: This SQL statement is open to injection attacks. I did this on purpose to generate dialogue in the comments section about how to address it with DB2 on i + Node.js. Let the conversation begin!

Restarting your application and navigating to /customers should reveal the results shown in Figure 2.

Our customer listing.
Our customer listing.

Next, we need to create a customer.jade file in the views directory to facilitate the previous res.render('customer', ...), as shown. Note that this view was singular and the other one was plural (customer.jade vs. customers.jade) as that’s a common convention.

h1=title
table
  tr
    td: b Customer Number
    td=result.CUSNUM
  tr
    td: b Last Name
    td=result.LSTNAM
  tr
    td: b Initial
    td=result.INIT
  tr
    td: b Street
    td=result.STREET
  tr
    td: b City State, Zip
    td= result.CITY + " " + result.STATE + ", " + result.ZIPCOD
a(href='/customers') Back

Restart the application, go to the /customers page and click on a customer. You should see a page similar to Figure 3.

Individual customer listing.
Individual customer listing.

More Insight

I hope you’ve gained insight as to how the ExpressJs framework operates with Node.js to create a simple Web application. As you might guess, we’ve only touched the tip of the iceberg and there are many more features to work through in future articles (e.g., ExpressJs “middleware” is an important topic). I’ve included the entire source for this app in the Litmis Bitbucket Node.js repo for reference.

[/et_pb_text][/et_pb_column][/et_pb_row][/et_pb_section]

One Response