Beyond Hello With Node.js
November 1, 2016 Aaron Bartell
In Why Node.js? we discussed Node.js and how to get up to speed with “hello world” from a program, the Node.js REPL (Read, Eval, Print, and Loop), and a web application. Now we will build on that knowledge by actually creating an application to show your team. A gent by the name of Rainer Ross recently posted a link to the IBM i Professionals LinkedIn group declaring the benefits of the new Webix framework. (Webix.com is freemium software. There are free versions and paid versions. Please adhere to the licensing.) Because of my comments on his post I received an inquiry from a frequent poster on the Midrange.com forums. I was asked how one might go about putting together a full working example with the database on IBM i with a request to show how all the pieces are connected. Below are the commands necessary to create a new Node.js project and initialize it with the ExpressJs framework. ExpressJs isn’t required to make this example work, but it will simplify the Node.js web server code. This example uses the zsh shell, which you can freely obtain from the IBM i Chroot project. % mkdir project1 && cd project1 % npm init % npm install express --save % npm install body-parser --save % npm install serve-static --save Let me briefly discuss those commands. I created project1 in my /home/aaron directory. The npm init command creates the package.json file and prompts you with various questions. Accept all the defaults by pressing the Enter key. The –save option at the end of npm install modifies the package.json file to have the specified module become a dependency of the project. Scanning through the Webix features, I’ve determined that loading DB2 data into a Webix Data Table is a good start that will overcome a number of technology hurdles. Below is a screenshot of the final product this tutorial is accomplishing. This DB2 data is obtained from table QIWS/QCUSTCDT, a sample customer database included with the IBM i operating system. Create file project1/public/list_customers.html and populate it with the following content. (I’ve also created a Bitbucket Snippet, which is easier to read because of color coding.) <!DOCTYPE html> <html> <head> <title>List Customers</title> <link rel="stylesheet" href="http://cdn.webix.com/edge/webix.css" type="text/css"> <script src="http://cdn.webix.com/edge/webix.js" type="text/javascript"></script> </head> <body> <h2>Customer Listing</h2> <div id="list_div"></div> <script type="text/javascript" charset="utf-8"> webix.ready(function(){ grida = webix.ui({ container:"list_div", view:"datatable", columns:[ { id:"CUSNUM", header:"Number", css:"rank"}, { id:"LSTNAM", header:[ "Last Name",{content:"textFilter"}], css:"rank"}, { id:"CITY", header:"City"}, { id:"CDTLMT", header:"Credit Limit"} ], autoheight:true, autowidth:true, url:"/data" }); }); </script> </body> </html> There are two primary sections to this HTML document. The first obtains the webix.css and webix.js files from the Webix CDN (Content Delivery Network). This also means we didn’t need to install Webix on the IBM i. The second section invokes the webix.ready(. . .) function. This is where we first see the simplicity of creating an aesthetically pleasing UI component. The basic concept is you are configuring the “datatable”, specifying what it should have for column names and where it should obtain the data from. In some ways this is similar to configuring the UI layer (*DSPF DDS) of an RPG program. Notice the container: property of this Webix widget is set to list_div, which is also the ID of a div further up in the HTML. This tellsWebix where to “paint” the resulting table. It’s important to note the url: property because that’s how we tell this widget where to get its data (in this case a Node.js web service). Now create file project1/server.js and place the following code into it. var db = require('/QOpenSys/QIBM/ProdData/Node/os400/db2i/lib/db2') var express = require('express') var app = express() var bodyParser = require('body-parser') var serveStatic = require('serve-static') app.use(serveStatic('public', {index: ['list_customers.html']})) app.use(bodyParser.urlencoded({ extended: false })) db.init() db.conn("*LOCAL") app.get('/data', function(req, res){ db.exec("SELECT * FROM QIWS.QCUSTCDT", function(result) { res.send(result) }); }); var port = process.env.PORT || 8080 app.listen(port) console.log('Running on port %d', port) The very top of server.js uses the require(. . .) API to bring in outside resources. This is a lot like /COPY in RPG. The seventh line declares that the index (a.k.a. root) of the website is list_customers.html, so when you go to http://myibm.com, substituting myibm.com with the name or IP address of your system, this file will be delivered. On line 13 we find the ‘/data’ route, which connects us to the url: property in list_customers.html. This is the code that will be invoked when a request to http://myibmi.com/data is made. As you can see, this is where we issue the SQL statement to retrieve a result set from DB2. Note that the data in the result variable is in JSON format, which we can conveniently send back down to the browser without converting it because that’s the format Webix is expecting. Nice! At this point it’s time to run the web server, as shown below. % node server.js Running on port 8080 Point your browser at http://myibmi.com:port/data, replacing myibmi.com with the name or IP address of your system and port with the port on which server.js is running, and you should see the data being returned by your Node.js web service, as shown below. Great! Now point your browser at http://myibmi.com:port, the root of the website. This will bring up list_customers.html, which will in turn load webix.css and webix.js, which will finally invoke the /data URL. The best way to learn the sequence of events is to watch them happen. Below is a screenshot of my Chrome browser with the Developer Tools window open. On final note, you’ll also notice the input field under the Last Name column heading. That is a filter that I configured in list_customers.html. Try typing in it and watch the list of entries gradually narrow down to only the last names with letters you’ve typed. This is a nice, simple, and easy feature to implement. If your Node.js web server is still running, go ahead and select Ctrl+C to end it. And that folks is the end! Hopefully this article convinces you to give Node.js on IBM i a try. Ping me if you need access to an IBM i in the cloud to test this stuff out on. If you have any other questions feel free to contact me directly at abartell@krengeltech.com. Aaron Bartell is Director of IBM i Innovation for Krengel Technology, Inc. Aaron facilitates adoption of open source technologies on IBM i through professional services, staff training, speaking engagements, and the authoring of best practices within industry publications and www.litmis.com. With a strong background in RPG application development, Aaron covers topics that enable IBM i shops to embrace today’s leading technologies including Ruby on Rails, Node.js, Git for RPG source change management and RSpec for unit testing RPG. Aaron is a passionate advocate of vibrant technology communities and the corresponding benefits available for today’s modern application developers. Connect with Aaron via email at abartell@krengeltech.com. Aaron lives with his wife and five children in Southern Minnesota. He enjoys the vast amounts of laughter having a young family brings, along with camping and music. He believes there’s no greater purpose than to give of our life and time to help others. RELATED STORY
|