Tutorial: Full-stack JavaScript for the Enterprise. Getting started with: Ext JS, Node.js, Express, MongoDB and Docker. (5)

Posted on in Docker Environment Ext JS 6 MongoDB Node JS NoSQL

This is part V of the tutorial, and covers how the Ext JS client app can consume the server Node.js API

Let the Ext JS app consume your API

By now we have a working back-end with Node, and a working front-end with Sencha.
Now we are ready to modify our Sencha app, so we can consume our back-end data and see it all in action!

It’s a simple client application with CRUD functionality for the Users model. With other words, we can create (POST) new users, read users and user details (GET), update existing users (PUT), and remove a user (DELETE).

I’ve added the codebase to Github, so let’s go through it, file by file. We will focus on the Classic Desktop view first, later we will create a mobile phone view.

Classic

https://github.com/savelee/docker-ext-client/blob/master/classic/src/Application.js

The application doesn’t auto create a viewport. Instead I’ve created a custom launch function, which either creates a login view (with the viewport plugin enabled), or the main interface with the viewport plugin enabled. It depends on the authorization token, if you have one on the device, it will auto login.

Take a look into the following files:

Here you can see the login panel. It’s actually a non-closable, non-draggable window, locked in the middle of the screen. The user can enter the username and password, which will be posted to the Node Express server. In case the username and password match with what’s in the database, it will return a token. In the success callback, we will save the token to the browser local storage.

Notice that we created two ViewControllers. One which will be shared by the classic and modern view. (This one contains the functionality to communicate with the back-end, since that’s view irrelevant.) The other ViewController, extends from the shared VC. This is the VC that contains an alias, and is bound to the classic view.

Note that although we Bcrypt the passwords in the database. It’s not secure to send passwords over HTTP. An attacker could very easily sniff the username and password that will be in the POST. Therefore enter: https://letsencrypt.org/. You could very easily create a free SSL certificate. You can find a guide here: https://letsencrypt.org/getting-started/ so you could set this up in no time.
It’s actually very easy, as long as you have console access to your webserver.

Let's dive further into our Ext JS code:

That’s the main viewport. It’s pretty much the same as the generated one from Sencha Cmd. We’ve just added a logout button. (which will destroy the main viewport, and remove the token from the localstorage.)

This is just a view with a grid. It shows a grid column for the first_name, last_name, email and an action column to remove the user from the grid. The functionality for this can be found in:

onRemove makes an AJAX call with the DELETE method, it makes a call to a URL that contains a user id.

When you click on a row in the grid, it will open a popup window, which contains the form.
I’ve implemented a renderConfig, which will hold the selected record. That way, as soon as the window will be created, and you run setRecord() on the form, it will run updateRecord() and load the record in the form, since the model fields map the form fields.

When you submit the form, you will get into the beforeSubmit() method. Here we just determine if the form contains a hidden form field, which contains the user URL. If it does, it means, the form contains data, so every change made will be a PUT request. If the form is empty, we will add a new user, and therefore we POST to the /users overview URL. The AJAX request itself, can be found in the shared user VC.

And that’s it for the desktop view.

desktop

Modern

The mobile view re-uses most of the functionality that’s already there. What is new, are the mobile (phone) views:

If there’s a token available, it will add the main view to the viewport, else it adds a login view.

The login view is a container, which centers a login form in the middle of the screen.
It calls the login view controller, for the onLogin() method. This method uses the doLogin() method from the shared login view controller, which contains the AJAX POST call, to request a token. Once logged in, it will add the token to the local storage, and it will remove the login view from the viewport, and instead add the main view to the viewport.

The main view is just a tabpanel, with for now, just one tab. It contains a hidden back button, which will be enabled once you are in a form. And it contains a logout button, which calls the onLogout() method, which removes the token, and resets the views.
It contains a user tab, which has a card layout. It can switch between a grid view which list all the users, or a form, to edit one user.

This is the list view. It contains an itemTpl with the first_name, last_name, email, username and password. Once you tap an item, it slides in the userform.

This form contains also a toolbar with a Delete button. This toolbar will be hidden, when you open the form via the Add button. But when you tap an item, it’s visible, and the form will be prefilled with data. It contains similar functionality as in the classic toolkit. It holds a config with the record.
updateRecord() will be called, every time when you run setRecord().

Feel free to download the code base and play around with it.

mobile

By the end of this part of the tutorial, you will understand how the Sencha Ext JS client can consume the Node.js server API. In the next blog posts we will focus on getting familiar with Docker.

Read the next part

https://www.leeboonstra.com/developer/tutorial-full-stack-javascript-for-the-enterprise-getting-started-with-ext-js-node-js-express-mongodb-and-docker-6/

Tutorial: Full-stack JavaScript for the Enterprise. Getting started with: Ext JS, Node.js, Express, MongoDB and Docker. (4)

Posted on in Environment Node JS

This is part IV of the tutorial, and covers: Setting up CORS on Node.js

Once we are done with all the tutorials, you will have a working back-end with Node.js / Express 4 and a working front-end, with Ext JS. Only there will be one problem. The client, can’t reach the JSON backend, because both are running on different ports / or different domains.

Cross-Origin Resource Sharing is a mechanism for allowing clients to interact with APIs that are hosted on a different domain. CORS works by requiring the server to include a specific set of headers that allow a browser to determine if and when cross-domain requests should be allowed. (For more information about CORS, take a look here: http://www.html5rocks.com/en/tutorials/cors/

Let’s open server/package.json, and add the following dependency:

"cors": "^2.7.1",

Open server/config/express.js, and add the following variable to the top of the file:

cors = require('cors'),

In the module.exports function, add the following line:

app.use(cors());

Now save both files, stop Nodemon, and run on the command-line:

$ npm install
$ nodemon app.js

This should fix your cross origin problem.

By the end of this part of the tutorial, your client can reach your server, without cross origin blockages. You learned about CORS.

Read the next part

https://www.leeboonstra.com/developer/tutorial-full-stack-javascript-for-the-enterprise-getting-started-with-ext-js-node-js-express-mongodb-and-docker-5/

Tutorial: Full-stack JavaScript for the Enterprise. Getting started with: Ext JS, Node.js, Express, MongoDB and Docker. (3)

Posted on in Docker MongoDB Node JS Sencha

This is part III of the tutorial, and covers how to setup a MongoDB NoSQL database.

MongoDB & Mongoose

MongoDB is a cross-platform document-oriented database, also known as a NoSQL database, This is different compared to a traditional table-based relational database like MySQL. Instead, the structure are JSON-like documents with dynamic schemas (MongoDB calls the format BSON), making the integration of data in certain types of applications easier and faster. MongoDB is developed by MongoDB Inc. and is published as free and open-source software under a combination of the GNU Affero General Public License and the Apache License.

Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment. It provides a model layer for interacting with your MongoDB collections from Node. This model layer provides a common location for implementing document validation, persistence indirection, and other logic that should be abstracted from the business layer.

Let’s integrate this with our Node back-end. Make sure you have MongoDB installed on your machine.

Create in the root of your server folder, the following file:

After that, run from the server folder the following command on the command-line:

$ npm install

This will install MongoDb, Mongoose and Nodemon, and if you don’t have Express yet, also express.

You will have to manually start MongoDB. Open a new terminal, and use the following command on the command-line:

$ mongod

We will change our server/config/express.js, to make sure bodyParser and csrf security works for posting forms.

Let’s create a couple more routes, to create a CRUD application. We need a route for creating new users (POST), a route to read one user (GET), a route to update one user (PUT) and a route to remove (DELETE) a particular user.

We will also need a register and authenticate route, which you will need to check if the username and password are correct. If so, it will return a JWT key, which you can store on your (mobile) client app.

Open server/routes.js and change to:

I’ve created another JS file (server/config/local_settings.js), which contains all sensitive information, such as passwords, secrets and keys. Now that this is a separate file, I don’t need to check in this file into my versioning system.

It contains this:

module.exports = {
  "secret": "mysecret",
  "database": "mongodb://localhost:27017/dockerextnode"
}

Next, we will replace the server/libs/user/index.js with the below piece of code. Take a look into the comments, to figure out what I am doing.

Now run the server:

$ nodemon app.js

We don’t have data in our Mongo database yet, so we will use CURL on the command-line, to get this fixed:

$ curl -H "Content-Type: application/json" -X POST  -d '{ "username": "lee", "password": "mypassword"  }' http://127.0.0.1:9000/register

Instead of Curl, you can also use Postman. There’s a Postman extension available for Google Chrome: https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en

Choose the method: POST
With the url: http://127.0.0.1:9000/register
Select the body tab, and create 2 x-www-form-urlencoded fields: username & password, also specify the values that belong to these fields.

See screenshot:

postman

Incase you want to test if all the values were correctly added to the database, you can run MongoDB from the command-line:

$ mongo dockerextnode
> db.users.find({}, function(err, users) { console.log(users) })

Want to checkout all my code? I hosted it on Github:
https://github.com/savelee/docker-node-server

By the end of this part of the tutorial, you will have a working JavaScript server, created with Node.js and Express. The next part of this tutorial will cover the setup of a MongoDB NoSQL database.

Read the next part

https://www.leeboonstra.com/developer/tutorial-full-stack-javascript-for-the-enterprise-getting-started-with-ext-js-node-js-express-mongodb-and-docker-4/

Tutorial: Full-stack JavaScript for the Enterprise. Getting started with: Ext JS, Node.js, Express, MongoDB and Docker. (2)

Posted on in Docker Ext JS 6 MongoDB Node JS

This is part II of the tutorial, and covers: JavaScript on the server.

Node.js: Setup the back-end with Express 4

Now that the client Sencha app is ready to be served, we need to create our server to display the Sencha app in the browser. What you see in the client folder, those are the development files (classes), which you use on your workstation.

We are going to use Express.js plus a couple of other modules to make our server app, serve pages, so let’s install all those.
(First navigate out the client folder, then..)

client $ cd ../server/
$ npm install --save express compression morgan errorhandler

Now let’s create the following folder structure:

$ mkdir -p config
$ mkdir -p components/errors
$ mkdir views

And the following files:

$ touch app.js
$ touch routes.js
$ touch config/index.js
$ touch config/express.js
$ touch components/errors/index.js
$ touch views/404.html

Let’s look into all the files:

In server/routes.js we define some configuration for the routes, like 404 and other routes.
The file looks like this:

In server/config/index.js we define some common configuration for the server:

And in server/config/express.js we setup Express to serve our files. Note that we point here to the production build of the Sencha app.

In server/components/errors/index.js we define app errors like how 404 should behave and what to respond with.

The server/views/index.html view:




<title>Webservice</title>

Finally the server/views/404.html view:




<title>Oops</title> <h1>404 Not Found</h1>

Now we are ready to start the server:

$ node app.js
Express server listening on 8080, in development mode.

You can now open your browser, the Node server, should serve the production version of your Sencha app. http://localhost:8080.

Before we move on, let’s create a very simple API route, which outputs json data. We will tweak the Sencha client app, so it retrieves the data from Node.

$ mkdir libs
$ cd libs
$ mkdir users
$ cd users
$ touch index.js 

Here’s the contents for the users/index.js file. Like I mentioned before, it doesn’t do anything special then outputting data. But this could be a great point to start for you.

Once you saved this file. We need to create a new route: http://localhost:8080/users/.
We will be able to test this route, when entered in the browser. Node.js needs to be (node app.js).

You can create this file, by opening server/routes.js and add the following route:

  app.route('/users')
    .get(function (req, res) {
        var us = new UsersService();
        us.getData(req, res);
    });

Want to checkout all my code? I hosted it on Github:
https://github.com/savelee/docker-node-server

By the end of this part of the tutorial, you will have a working JavaScript server, created with Node.js and Express. The next part of this tutorial will cover the setup of a MongoDB NoSQL database.

Read the next part

https://www.leeboonstra.com/developer/tutorial-full-stack-javascript-for-the-enterprise-getting-started-with-ext-js-node-js-express-mongodb-and-docker-3/

Tutorial: Full-stack JavaScript for the Enterprise. Getting started with: Ext JS, Node.js, Express, MongoDB and Docker. (1)

Posted on in Docker Ext JS 6 JavaScript Node JS

This is part I of the tutorial, and covers: JavaScript on the client.

Yeah you are correct, when you have a web project, optimized for production, you can use FTP and simple upload the folder on your server. That’s easy, and when you only have a simple HTML5/JS/CSS app, or an application with a PHP back-end on Apache this probably works fine for you. But what, if you have a very complex application, or you are working on an application with a large team? You probably want to automate as much as possible, and make every live build easy.

This tutorial will show you, how you can create an app where we will use JavaScript on the client (an Ext JS 6 app), and JavaScript on the server (Node.js with Express). Maybe you have played around with Node.js before. When you configured a Node.js app with Express etc, you will probably need to install packages via the the NPM packages manager. These are all dependencies. Now imagine you’ve created on your local workstation a fully working back-end, with Node.js and a MongoDB database. You had to install a lot of packages, and make some configurations on your system. This can be a configuration where you save environment passwords, or maybe even hardware configurations.
What you don’t want, is to manually replicate all the settings and configurations you made locally, again on the server. Ideally, you will take whatever you have on your local machine, and take that over. Maybe you even want to run the same operating system and hardware on production. This is where Docker comes into play.

With Docker you can create an isolated container with all the files such as dependencies and binaries for your app to run, making it easier to ship and deploy. It simplifies the packaging, distribution, installation and execution of (complex) applications.
So, what is an isolated container? These containers are self-contained, preconfigured packages that a user can fetch and run with just a single command via the Docker hub (like Github, but for Docker). By keeping different software components separated in containers they can also be easily updated or removed without influencing each other.

About Docker

With Docker you can create an isolated container with all the files such as dependencies and binaries for your app to run, making it easier to ship and deploy. It simplifies the packaging, distribution, installation and execution of (complex) applications.
So, what is an isolated container? These containers are self-contained, preconfigured packages that a user can fetch and run with just a single command via the Docker hub (like Github, but for Docker). By keeping different software components separated in containers they can also be easily updated or removed without influencing each other.

What you will need:

For this tutorial I used: Ext JS 6 and Cmd 6.0.2, Node.js 5.8 with NPM installed and Docker 1.10.

Please install the following:

Ext JS 6: Create the client app

Create the following folder somewhere on your hard drive: dockerextnode.

Put a temporary copy of the Sencha SDK inside dockerextnode, (for example ext-6.0.2). If you don’t have Ext JS yet, feel free to download the trial: https://www.sencha.com/products/evaluate/

Open Windows Command / Terminal, and navigate on the command-line to the dockerextnode folder. From there enter the following commands:

$ mkdir server
$ cd ext-6.0.2
$ sencha generate app Client ../client

You’ve now created 2 folders. The server* folder, which will contain the Node code later and the **client folder, which contains the copy of the Sencha SDK together with a demo app.

Let’s remove the temp folder:

$ cd ..
$ rm -Rf ext-6.0.2

You’ve now removed the temp. Sencha SDK folder. We can now, start testing our Sencha demo app:

$ cd client
$ sencha app build production
$ sencha app watch

This command will spin off, a Jetty server on http://127.0.0.1:1841. Visit this page in the browser, and confirm you see the Sencha demo app. Once, you’ve seen the demo app, we can stop the server, by stopping the sencha app watch (with CTRL + C for example). We will keep the demo app like it is, but this could be a nice starting point for you, when you want to create your own app.

NOTE:
By default, the sencha app watch command starts the development server on the internal IP at port 1841. If you want to change the server’s port, for example to port 8082, you will have to start the server via the web command. This command will only bootu p an internal server, and won’t “watch” your app for changes. $ sencha web -port 8082 start

Want to checkout all my code? I hosted it on Github:
https://github.com/savelee/docker-ext-client

By the end of this part of the tutorial, you will have a working JavaScript client app, created with Sencha Cmd and Ext JS 6. The next part of this tutorial will cover the setup for creating a Node.js with Express app.*

 

ExtJS6-demo-app

Read the next part

https://www.leeboonstra.com/developer/tutorial-full-stack-javascript-for-the-enterprise-getting-started-with-ext-js-node-js-express-mongodb-and-docker-2/

Node Connect example

Posted on in JavaScript Node JS

The example below can be easily replaced with Node Connect. Just with a few lines.
app.js

var http = require('http');
var path = require('path');
var fs = require('fs');
var extensions = { 
   ".html" : 'text/html', 
   ".css" : 'text/css', 
   ".js" : 'application/javascript',
   ".json" : 'application/javascript', 
   ".png" : 'images/png', 
   ".gif" : 'images/gif', 
   ".jpg" : 'images/jpeg' 
} 

http.createServer(function(req, res){ 
   var filename = path.basename(req.url) || 'index.html', 
      ext = path.extname(filename), 
      dir = path.dirname(req.url).substring(1), 
      localPath = __dirname + "/views/"; 

     //console.log(localPath); 
     if(extensions[ext]){
        localPath += (dir ? dir + "/" : "") + filename; 
        path.exists(localPath, function(exists){ 
           if(exists){ 
              getFile(localPath, extensions[ext], res) 
           } else { 
              res.writeHead(404); res.end();
           } 
        }); 
     }
}).listen(8000, '127.0.0.1'); 

getFile = function(localPath, mimeType, res){ 
   fs.readFile(localPath, function(err, contents){ 
   if(!err){ 
      res.writeHead(200, { 
         "Content-Type" : mimeType, 
         "Content-Length" : contents.length 
      }); 
      res.end(contents); 
   } else { 
      res.writeHead(500); 
      res.end(); 
   } 
});

Now install Connect:

$ sudo npm install connect

app.js

var connect = require("connect");
connect().use(connect.static(__dirname + "/views")).listen(8000);

Hello World with Node.js

Posted on in JavaScript Node JS

See the example below for an easy Hello World example with Node.js. Create a Node.JS server and serve a hardcoded response, with content-type: “text/html”. And listen to localhost:8000 in your browser to see the result. In your project folder create an app.js file:

var http = require('http');
http.createServer(function(req, res){ 
   var html = BoilerplateHello World"; 
   res.writeHead(200, { 
      'Content-Type' : 'text/html', 'Content-Length' : html.length 
   }); 
   res.end(html);
}).listen(8000,'127.0.0.1');

With the above example you can’t create a real-life application. Let’s create an MVC folder structure in your project folder. By creating the following folders: “controller”, “model”, “views”. In the “views” directory, create here an index.html file. With the following content:

Then change your app.js file like the example below to retrieve the index.html file from the views folder:

var http = require('http');
var path = require('path');
var fs = require('fs');
http.createServer(function(req, res){ 
   var filename = path.basename(req.url) || 'index.html', 
   ext = path.extname(filename), 
   localPath = __dirname + "/views/"; 
   //console.log(localPath); 

   if(ext == ".html"){ 
      localPath += filename; 
      path.exists(localPath, function(exists){ 
         if(exists){ 
            getFile(localPath, res) 
         } else { 
            res.writeHead(404); 
            res.end(); 
         } 
       }); 
    }
}).listen(8000, '127.0.0.1'); 
getFile = function(localPath,res){ 
   fs.readFile(localPath, function(err, contents){ 
      if(!err){ 
         res.end(contents); 
      } else { 
         res.writeHead(500); 
         res.end(); 
      } 
});

Auto restart node after code changes

Posted on in JavaScript Node JS

When you are sick and tired of restarting your node app in the terminal (CTRL+C) on every code change you make then you can automate this process. Actually it’s really simple. Install Nodemon via the package manager.

$ sudo npm install nodemon -p

When you want to check if it correctly installed and on which version you are running Nodemon:

$ nodemon -v
0.6.14

Is everything correctly set? You can start Nodemon, by typing the following command in the root of your current node project. For example:

$ nodemon app.js
9 Apr 20:15:23 - [nodemon] watching: /Users/lee/Projects/nodejs/www
9 Apr 20:15:23 - [nodemon] starting 'node app.js'

Installing Node and NPM on MAC OSX

Posted on in Environment Node JS

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

This assumes that Git is already installed and available on the command-line. Since the technology Node.js is quiet new, check at http://nodejs.org/ what the latest stable version of node.js is. For this example the latest version is v0.6.14. Open your terminal and start typing the following commands:

$ git clone git://github.com/joyent/node.git
$ cd node
$ git checkout v0.6.14
$ ./configure
$ make
$ sudo make install

Now Node.js is installed, you should also download the Node Package Manager. It’s no longer necessary to install npm separately, but if you want you can install this via the command-line as well. Use the following command:

$ curl http://npmjs.org/install.sh | sh

As an extra let’s also install MongoDB, is a large scalable high performance NoSQL database.

$ npm install mongojs