MEAN web development #4: All aboard the Node.js Express!

Hi everyone. After my little excursion to Polymer we’re back at MEAN web development! In my previous MEAN post about Node.js I asked you what you wanted to read next, Express or MongoDB. I got a request for Express, so that’s what this post will be about. Don’t worry, we’ll get to MongoDB later. If you’re not up and running yet you can check out my previous posts.

  1. MEAN web development #1: MEAN, the what and why
  2. MEAN web development #2: Node.js in the back
  3. MEAN web development #3: More Node.js
  4. MEAN web development #4: All aboard the Node.js Express!
  5. MEAN web development #5: Jade and Express
  6. MEAN web development #6: AngularJS in the front
  7. MEAN web development #7: MongoDB and Mongoose
  8. MEAN web development #8: Sockets will rock your socks!
  9. MEAN web development #9: Some last remarks

The code examples for this post are, as usual, on my GitHub account in the mean4-blog repository.

Also be sure to follow me on Twitter @sanderrossel for industry updates and more blogs on MEAN, Node.js, Express, MongoDB, AngularJS and related technologies.

Express

Express is a pretty generic framework for Node.js, or a minimal and flexible Node.js web application framework as they put it.
Node.js is pretty bare bones and has only the most basic server functionality. That’s a good thing because that means other people, like the Express team, can do things their way. And so Express just handles a lot of the low level work for you. Parsing paths and queries, check; routing, check; templating, check. So it’s no wonder that Express is a pretty popular Node.js framework! There are some alternatives for Express, like Koa and Hapi, but I won’t discuss those here.

I have already explained how to install Node.js and add Express to your project in MEAN web development #1: MEAN, the what and why and we’ve used some Express in MEAN web development #2: Node.js in the back. So if you haven’t read those articles yet I suggest you read them now. Don’t forget about nodemon either, a very nice tool for testing Node.js applications!

Starting from this post I’m also just going to host our sites on port 80 (instead of 1337). This has the advantage that we can just visit localhost instead of localhost:portNumber because 80 is the default HTTP port. That said, other applications might use port 80 (like SQL Server Management Studio Reporting Services). If port 80 isn’t working for you simply use another port (or make port 80 available by closing the application that’s using it).

Routing

In MEAN web development #2: Node.js in the back we’ve already seen some routing examples. Let’s go over that again real quick and see some other really nice routing features of Express.js!

So let’s say you have a very simple website with a homepage and an about page. Your Node.js Express server JavaScript file may look a bit like this.

var express = require('express');
var app = express();

app.get(['/', '/index'], function(req, res) {
    res.send('This is the homepage!');
});

app.get('/about', function(req, res) {
    res.send('This is the about page!');
});

var server = app.listen(80, '127.0.0.1');

That’s cool, but what if you wanted to log every request you got? Sure, you could create a function and call it in both handlers, but if you get a lot of handlers that will become a little tiresome. Especially when you’re going to move your routing to external files. And after you’ve added the logging you want to implement some login handler and some blacklist checker and… Well you get the point.
What I haven’t told you yet is that you can chain request handlers so you can reuse them. Let’s check that out. For your homepage it may look like this.

var express = require('express');
var app = express();

app.get(['/', '/index'], function(req, res, next) {
        console.log(req.originalUrl + ' requested @ ' + new Date().toISOString());
        next();
    }, function(req, res) {
        res.send('This is the homepage.');
});

var server = app.listen(80, '127.0.0.1');

By specifying the next parameter in the first callback function and executing it the next handler will be called. Failing to either call next() or res.send() will make your website very unresponsive (it just freezes, so don’t forget). So here we get a logging of each request to our homepage.

And now we can easily refactor that and implement it for the about page too.

var express = require('express');
var app = express();

var logger = function(req, res, next) {
    console.log(req.originalUrl + ' requested @ ' + new Date().toISOString());
    next();
};

app.get(['/', '/index'], logger, function(req, res) {
    res.send('This is the homepage.');
});

app.get('/about', logger, function(req, res) {
    res.send('This is the about page.');
});

var server = app.listen(80, '127.0.0.1');

Now let’s add a blacklisted handler to our site. Usually you would have some list of blacklisted IP addresses and reject them access, but since we’re testing from localhost I’m just going to check for a blacklisted query parameter. Notice that the blacklisted function either calls res.send() or next(). We can pass in an array of handlers to app.get(), so that makes our lives a little easier.

var express = require('express');
var app = express();

var logger = function(req, res, next) {
    console.log(req.originalUrl + ' requested @ ' + new Date().toISOString());
    next();
};

var blacklisted = function(req, res, next) {
    if (req.query.blacklisted == 'true') {
        res.send('You are blacklisted on this site!');
    } else {
        next();
    };
};

var globalReqHandlers = [logger, blacklisted];

app.get(['/', '/index'], globalReqHandlers, function(req, res) {
    res.send('This is the homepage.');
});

app.get('/about', globalReqHandlers, function(req, res) {
    res.send('This is the about page.');
});

var server = app.listen(80, '127.0.0.1');

You can get ‘blacklisted’ by adding “?blacklisted=true” to the end of your URL, for example “localhost/about?blacklisted=true”. So that’s pretty cool! But it gets better. We can use app.use(). This will append some request handlers (also called middleware) to the routings. Be sure you add your handlers in the correct order as they’re executed in the same order you added them. So this would look as follows.

var globalReqHandlers = [logger, blacklisted];

app.use('/', globalReqHandlers);

app.get(['/', '/index'], function(req, res) {
    res.send('This is the homepage.');
});

app.get('/about', function(req, res) {
    res.send('This is the about page.');
});

Notice that the listener for the homepage and the about page no longer have the globalReqHandlers specified, but the requests will still be logged.

So let’s add a little admin panel. Whenever someone accesses the admin panel we want to make sure this user is an admin. How would this go?

app.use('/', globalReqHandlers);
app.use('/admin', function(req, res, next) {
    if (req.query.admin == 'true') {
        next();
    } else {
        res.send('You are not an admin on this site!');
    };
});

/* Homepage and about... */

app.get('/admin', function(req, res) {
    res.send('This is the admin panel.');
});

app.get('/admin/users', function(req, res) {
    res.send('This is the admin users page.');
});

Whenever you now try to access an admin page you need to be an admin (by adding “?admin=true” at the end of your URL). Notice that a request for an admin page still gets logged and checked for the blacklist. The homepage and about page, however, don’t check if the user is an admin.

So you can imagine this stuff clutters up your server file pretty quickly. Let’s move these routing handlers to separate files. If you’re unfamiliar with modules in Node.js I suggest you read my previous MEAN article, MEAN web development #3: More Node.js.

So create two files in node_modules, called routing.js and routingAdmin.js.

Here is the code for routing.js.

var express = require('express');
var router = express.Router();

var logger = function(req, res, next) {
    console.log(req.originalUrl + ' requested @ ' + new Date().toISOString());
    next();
};

var blacklisted = function(req, res, next) {
    if (req.query.blacklisted == 'true') {
        res.send('You are blacklisted on this site!');
    } else {
        next();
    };
};

var globalReqHandlers = [logger, blacklisted];

router.use('/', globalReqHandlers);

router.get(['/', '/index'], function(req, res) {
    res.send('This is the homepage.');
});

router.get('/about', function(req, res) {
    res.send('This is the about page.');
});

module.exports = router;

And here’s the code for adminRouting.js.

var express = require('express');
var router = express.Router();

router.use('/', function(req, res, next) {
    if (req.query.admin == 'true') {
        next();
    } else {
        res.send('You are not an admin on this site!');
    };
});

router.get('/', function(req, res) {
    res.send('This is the admin panel.');
});

router.get('/users', function(req, res) {
    res.send('This is the admin users page.');
});

module.exports = router;

So we’re using the Express.Router object and do much the same to it as we did with app earlier. Do notice that I’m just mapping to ‘/’ and ‘/users’ in the adminRouter though. In our server file we can now use these modules as follows.

var express = require('express');
var routing = require('routing');
var adminRouting = require('adminRouting');
var app = express();

app.use('/', routing);
app.use('/admin', adminRouting);

var server = app.listen(80, '127.0.0.1');

So as you can see I can now use and reuse the routing! And it is here that I map the admin routings to /admin. So how cool is that? I thought so too!

There’s one last thing I’d like to show you. I won’t implement it, but I thought you’d like to know it’s there since it’s pretty cool! You can use app.route() to chain HTTP methods to a request. So far we’ve only seen GET (app.get()), but app has a method for each HTTP method (app.post(), app.put(), app.delete()…).

app.route('/admin/users')
    .get(function(req, res, next) {
        // Handle GET here...
    })
    .post(function(req, res, next) {
        // Handle POST here...
    }) // etc.
);

404

So now that we have all of our routing in place we can define a handler for the well known 404! So if all else fails, and a request couldn’t be handled, we return this. Luckily that’s really very easy.

app.use('*', function(req, res) {
    res.status(404).send("Well, looks like we've got a four-o-four, boys! (That mean the page was not found)");
});

We simply hook up another middleware! The ‘*’ is a wildcard character and means it responds to anything we throw at it. For this reason it’s very important to put the 404 handler after all your other handlers! Remember that your handlers are executed in the order you add them to your app, so if this one is added before anything else this will handle the request and anything after this will be ignored. Notice I’m setting the status to 404, which is the HTTP status code for “Not Found” and let’s the browser know the page couldn’t be found. You can set any status using Response.status(), but usually you won’t have to. Other status codes include 200, OK (the default); 202, Accepted; 400, Bad Request; 403, Forbidden and 500, Bad Request (and there’s lots more).

I’d like to focus on the wildcard for a bit. There are a few patterns you can match, including any Regular Expression.
* means just any character(s). So ‘/sander‘ would match ‘sanderrossel’, but also ‘sanderexpress’ or just ‘sander’. ‘/sanderss*’ would match ‘sanderrossel’ and ‘sanderexpress’, but not ‘sandernodejs’.
A character may appear more than once. You can use a plus symbol, for example ‘/go+gle’ (coun’t the amount of zeroes and navigate to that page in the search results?). Of course it matches ‘gogle’, ‘google’, ‘gooogle’ and so on.
You can also mix in optional characters using the questionmark. For example ‘/express?’ would match ‘express’ and ‘expres’.
You can group characters using parenthesis. ‘/express(js)?’ matches ‘express’ and ‘expressjs’, but not ‘expressj’.
Why would you use this? You can now write a single handler for ‘page’, ‘page.htm’, ‘page.html’, etc. That’s pretty neat!

You can play around with it by adding the following middleware to your server (before the 404) and browsing to localhost/yourpatternhere (or ‘yourcoolpattttern’, ‘yourpatternhere’ or ‘yourawesomepattttternhere’, but not ‘yourpatter’ or ‘yourpaternhere’).

app.get('/your*patt+ern(here)?', function(req, res) {
    res.send('Matched the pattern!');
});

Error handling

So what happens when something goes wrong? Perhaps your connection to the database failed when looking up that blacklist. Luckily adding some error handling isn’t difficult. Just add another middleware! The error handler needs to have four parameters passed to it, whether you use them or not. That way Express knows it’s an error handler.

app.use('/', function(err, req, res, next) {
    console.error(err.stack);
    res.status(500).send('Oops, looks like you broke something!');
});

You need to add that even after your 404, after all 404-ing may cause an error! So now we only need to have an error to test this. You can add the following code (before the 404!) and browse to localhost/error.

app.get('/error', function(req, res) {
    // something is undefined.
    var error = 1 / something;
    res.send('Code will never come here.');
});

Of course you can add specific error handlers for specific pages. Simply change the path of your handler. For example, the following code will only handle any errors on admin pages.

app.use('/admin', function(err, req, res, next) {
    console.error(err.stack);
    res.status(500).send("Oops, looks like you broke something! That's not very admin-ish of you!");
});

Do notice I’m setting the status to 500. You can use the error object for information about the error.

And of course you can chain error handlers. Keep in mind that only the first handler needs the err parameter!

var logger = function(err, req, res, next) {
    console.error(err.stack);
    next();
};

var dbLogger = function(req, res, next) {
    console.log('Error logged to DB.');
    next();
};

var serveErrPage = function(req, res, next) {
    res.status(500).send('Oops, looks like you broke something!');
};

app.use('/', logger, dbLogger, serveErrPage);

And what happens if even your error handling fails? Guess you better set up a safety net.

app.use('/', logger, dbLogger, serveErrPage);
app.use('/', function(err, req, res, next) {
    // Everything failed...
    res.status(500).send('Even the error handling is bugged...');
});

And we can generate an optional error by, you guessed it, passing it in as a query parameter. Let’s handle it in the logger function.

var logger = function(err, req, res, next) {
    if (req.query.err == 'true') {
        var error = 1 / somethingElse;
    };
    console.error(err.stack);
    next();
};

So localhost/error for the regular error handling. localhost/error?err=true to generate an error in the error handling.

Of course you could’ve put the error handlers in the routing file too! I won’t do that, but just know that it’s an option.

One last thing. The app.get(), app.use() etc. all have a path parameter, it’s the ‘/’, ‘/admin’ parameter. It’s optional. I’ve specified it every time for clarity, but you may omit it and it will default to ‘/’.
So app.use(‘/’, handler) is the same thing as app.use(handler).

In this post we’ve taken a good deep look at the routing functionality of Express. As you can see it’s all pretty easy. There’s more you can do with Express, especially when you install some third-party middleware, like cookie-parser, cookie-session, express-session or compression.
There’s an important feature of Express that we haven’t seen yet, which is templating. You can use template engines, like Jade or Mustache, with Node.js and Express. We’ll use Express and Jade in a later post!

And, as usual, I’m going to recommend some books. First there’s the Succinctly ebooks by Syncfusion that I keep recommending because they’re great and they’re free. If you feel you’re still not up to speed, or looking to get up to speed, with Node.js and Express take a look at JavaScript Succinctly, Node.js Succinctly and HTTP Succinctly.
I can also recommend the books by Manning Publications. They have some good stuff on Node.js and Express!

Stay tuned!

Polymer for reusable web components

Wait, what? No MEAN Web Development #4? If you’ve been following my blog you’ll know I’m in the middle of a series on MEAN Web Development. Don’t worry, I’ll get back on that!

The thing is I went to an event by CoolBlue, a Dutch webshop, last week and they had a talk on their own CDN and on Polymer 0.5. While the CoolBlue CDN is quite interesting it isn’t a very good topic to blog about. Polymer looked pretty cool too though, so I wanted to blog about that while it’s still sort of fresh in my memory. Of course I won’t be writing down exactly what was told at the CoolBlue presentation. Instead I’m going to hook in on it. You probably weren’t there so let me give you a quick recap.

“Polymer 0.5, the version CoolBlue used, is great if you’re using Chrome. Polymer 0.8 (which is still in alpha) will make lots of breaking changes to the API, but it contains the proposed API for version 1.0 and fixes some shortcomings, like performance, from 0.5.”

So if anything Polymer isn’t quite production ready. I’ve never been much of an early adopter, but today that’s going to change. In this blog I’ll be discussing Polymer 0.9 (the plan was 0.8, but then 0.9 came out while I was writing)!

You can find the source code of the examples on my GitHub account in the polymer-blog repository. You’ll need to run them from a web server (I’ll explain how to do that in this post).

Also be sure to follow me on Twitter @sanderrossel for news and articles on (web) development.

Web components

But what exactly is Polymer? Polymer is a library for creating web components developed by Google. But what is a web component? Actually there’s an entire website dedicated to teaching you about web components, WebComponents.org. Let me give you a quick summary.
Web components allow you to create custom HTML elements that contain other HTML, CSS and JavaScript. That way you can, theoretically, build websites by composing HTML, rather than nest HTML, call some JavaScript, add some CSS, throw it in the mixer, and get a mess.
So by encapsulating HTML, CSS and JavaScript we can create custom HTML that we can (re)use to compose new components or pages.

An important part of web components is the Shadow DOM (sounds like something from a video game, right?). Anyway, the shadow DOM is like ‘invisible’ HTML in your HTML document, a DOM that exists next to your DOM. Think of it as a sub-DOM, but that you can’t see. So far only Chrome and Opera support the shadow DOM.

For that reason web components are currently mostly implemented using polyfills, a downloadable piece of code that fakes native support by adding modern HTML and CSS functionality to older browsers as if they were part of the standard API.

As you can see web components still has a long way to go before it’ll be supported natively by browsers and reach maturity, but luckily nothing is stopping us from already taking a look at it today. And if nothing of that rang any bells, don’t worry, it’ll become clear once we look at some examples!

Bower

First things first. We need to get Polymer up and running in our project. We have a couple of ways to do this. First, and this is the recommended way, we can install Polymer by using Bower, a package manager for the web. Alternatively we can download some zip file containing all necessary files and use that. Lastly we can pull Polymer directly from GitHub and get all the related software manually.

So let’s go with Bower. I’m assuming you’re not familiar with Bower yet (neither am I), so I’ll walk you through it step by step (assuming you’re on a Windows system). If you already know Bower, or you’d like to install Polymer using one of the other proposed methods, feel free to skip this part. I won’t be discussing the other methods.

First we need to install Bower. Even though Bower is a package manager we need a package manager to install it. More specifically we need npm (and also Node.js). You can get both on the Node.js website. Luck has it that I already discussed how to install Node.js and npm in a previous blog, MEAN web development #1: MEAN, the what and why. So I suggest you read it, or at least the part on installing Node.js and Express (that last part shows you how to use npm).

Once you’ve got Node.js and npm installed you’ll need Git. No doubt you’ve heard about Git. It’s the source control system developed by mr. Linux, Linus Torvalds, himself. You can get Git from their downloads page. When installing be sure to check the box that says “Use Git from the Windows Command Prompt”! Other than that you can leave all the defaults in place.
If you use GitHub and already have the GitHub software installed you’ll still need to install Git. GitHub is a client for the GitHub website and though it does use Git, it doesn’t use it on your local machine.

Now that we have all we need to use Bower we can actually install Bower! Open up a command prompt (yes, Bower uses the command prompt too…) and install it using npm.

npm install bower -g

Now installing Polymer is a breeze. Create a folder where you’d like to have your project, navigate to it using your command prompt and install Polymer like you would do when using npm (their syntax is very much the same).

cd "C:\MyProjects\PolymerProject\"
bower install Polymer/polymer#^0.9.0

Alternatively you could create a bower.json file, much like the Node.js package.json, and keep track of your installed packages. You can create a bower.json file manually or use the command prompt and walk through some sort of setup. In the command prompt use the following command (still in your project folder).

bower init

If you want to leave a field blank just press enter. Now you can install packages using –save and the bower.json will be updated automatically.

bower install Polymer/polymer#^0.9.0 --save

You can also omit the version and just get the latest.

After installing Polymer my bower.json looked like this.

{
    "name": "polymer-blog",
    "version": "1.0.0",
    "authors": [
        "Sander Rossel"
    ],
    "main": "index.html",
    "homepage": "http://sanderrossel.com",
    "ignore": [
        "**/.*",
        "node_modules",
        "bower_components",
        "test",
        "tests"
    ],
    "dependencies": {
        "polymer": "Polymer/polymer#~0.9.0"
    }
}

Yours may look differently dependent on what you entered in the setup.

There’s a lot more you can do with Bower, but I’ll leave it at this as this blog is actually about Polymer!

Polymer

And then we’re finally getting to Polymer! Unfortunately, because of some browser security issues, we’re going to need to run our HTML, CSS and JavaScript examples on an actual web server. No problem of course, since I already blogged about that too. So read the part “Setting up your environment” from Web development #4: PHP in the back and once you’ve installed XAMPP we’re ready to go. I’d like to make a small addition to the paragraph from that post. The default port 80 was in use on my computer (it happens). If you have the same problem either shut down the program that is using port 80 or change the port in XAMPP by going to Config -> Service and Port Settings -> Apache and change the main port.

Because we need a server I’ve put all of the examples on the same index.html page. As I already mentioned, the shadow DOM is pretty important when creating Polymer web components. By default Polymer puts the HTML tree in the main DOM though, so we’ll want to turn this off and put it in the shadow DOM instead (so the Polymer components are really self-contained). As far as I understand putting the components HTML in the shadow DOM will be default when Polymer 1.0 is officially released, for now I’m putting the following script in my header though.

<script>
    window.Polymer = window.Polymer || {};
    window.Polymer.dom = 'shadow';
</script>

On to the example. First you’ll need to install Polymer in your htdocs folder. After that create another folder called “components”. In components create a file called “hello-polymer.html”. In that file put the following HTML.

<dom-module id="hello-polymer">
    <template>
        <h2>Hello, Polymer!</h2>
        <p>This is our Hello World example.</p>
    </template>
</dom-module>
<script>
    Polymer({is: "hello-polymer"});
</script>

Now in your htdocs folder create an index.html file and put the following HTML in it.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Hello, Polymer!</title>
        <script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
        <link rel="import" href="bower_components/polymer/polymer.html">
        <link rel="import" href="components/hello-polymer.html">
    </head>
    <body>
        <hello-polymer></hello-polymer>
    </body>
</html>

So let’s first look at the hello-polymer.html file. We start off by opening a dom-module element. Note that this is not an HTML standard! We can recognize non-standard elements by the hyphen (- symbol) in the name. For that reason, the value of our id attribute must contain at least one hyphen. The id indicates the name of  our custom element. So I’ve called it hello-polymer.
Within the dom-module element we’ll find a template element. That’s where our HTML goes. I’ve simply put an h2 header and a little paragraph in it. So that’s two elements.
Last, but not least, we need to register our custom element. We can do this by calling the Polymer function and passing it an object with the is-property and setting it to the name of our custom element.
So that’s it!

Now how can we use this custom element we just made? In the index.html you’ll need some imports. First you’ll need webcomponents-lite.min.js, second you’ll need polymer.html and last you’ll need our custom element. It’s actually these link elements that require us to use a server, as Chrome is pretty strict with linking HTML on your page.
So now we can just use our custom element! <hello-polymer></hello-polymer> is all it takes. Try it out by browsing to localhost.
Even though our body contains just one element, we can see two! Awesome!

So let’s make that a little bit more exciting. Create another file in the components folder, I’ve called it “expandable-hello-polymer.html”, and put the following code in it.

<dom-module id="expandable-hello-polymer">
    <style>
        .invisible {
            display: none;
        }
    </style>
    <template>
        <button id="btn">Click me!</button>
        <div id="body">
            <h2>Hello, Polymer!</h2>
            <p>This is our expandable Hello World example.</p>
        </div>
    </template>
</dom-module>
<script>
    Polymer({
        is: "expandable-hello-polymer",
        ready: function() {
            var btn = document.getElementById('btn');
            btn.onclick = function() {
                var body = document.getElementById('body');
                body.classList.toggle('invisible');
            };
        }
    });
</script>

In this example I’ve added a little CSS in the style element. The template contains a little more HTML too. The real trick lies in the script though. I’ve defined the ready function on the object passed to the Polymer function. Ready is executed, well, when the element is ready. The JavaScript itself is not very exciting, so I won’t get in on that.

Now what if we did the following in the example above?

<div id="body">
    <hello-polymer></hello-polymer>
</div>

That would’ve worked too! We can just use custom elements in our custom elements. We need to make sure the custom element we want to use is loaded though, we can load them in the current file (I’d recommend that) or in the file where we load our custom elements.

There’s still a little problem with the JavaScript in the above example. What if we have more elements with the id “btn”? After all, our document using the custom element doesn’t know about the button, so it might have another button with the same id. Which button will the above code fetch, the local one or the other one we don’t know about yet? This is especially tricky when not using the shadow DOM. We don’t know so let’s fix this problem. We can actually use the this object in the ready function to get access to the local DOM only. Notice that I’ve aliased this to that, since this won’t be this in the onclick event (hooray for JavaScript…).

ready: function() {
    var that = this;
    var btn = that.$.btn;
    btn.onclick = function() {
        var body = that.$.body;
        body.classList.toggle('invisible');
    };
}

So we can use this.$.elementId to get any element.  Alternatively we could use this.$$(selector) to get dynamically injected elements. $$ only returns the first found element.

And of course we can use it as follows.

<expandable-hello-polymer></expandable-hello-polymer>

In the example above you’ll notice that the text in the paragraph is now equal to the text in the hello-polymer example and we can’t change that. So what if we did want to change values inside our custom web component from the outside? The next example shows how we can use binding and how we can change attributes from outside of the Polymer component.

<dom-module id="attributes-polymer">
    <template>
        <span>This is <span>{{firstname}}</span> <span>{{lastname}}</span>'s custom element!</span>
    </template>
</dom-module>

<script>
    Polymer({
        is: "attributes-polymer",
        properties: {
            firstname: "",
            lastname: ""
        }
    });
</script>

So here we see that Polymer supports binding. If you’re familiar with AngularJS you’ll recognize the syntax. You can see we pass an object to the properties in the Polymer function. In these properties we specify the attributes we can use within this Polymer component, so firstname and lastname (attributes can’t have capitals). Then with the {{attribute}} syntax we can (two-way) bind to them. There’s an alternative syntax, [[attribute]], that indicates one-way binding. Binding is not possible with string concatenation, so I’ve put the bindings in their own span elements, that way we don’t need to concatenate.
Now in the index.html we can have the following.

<!DOCTYPE html>
<html>
    <head>
        <!-- ... -->
    </head>
    <body>
        <div>
            <label for="firstNameInput">Whose element is this?</label>
            <input id="firstNameInput" type="text" />
            <input id="lastNameInput" type="text" />
 <button id="btn">Change name</button>
        </div>
        <attributes-polymer id="elem" firstname="Sander" lastname="Rossel"></attributes-polymer>
    </body>
</html>

<script>
    var btn = document.getElementById('btn');
    btn.onclick = function() {
        var firstName = document.getElementById('firstNameInput').value;
        var lastName = document.getElementById('lastNameInput').value;
        var elem = document.getElementById('elem');
        elem.firstname = firstName;
        elem.lastname = lastName;
    };
</script>

And as you can see the values of firstname and lastname change value when you press the button.

There’s one last example I want to look into, two-way binding. This is a powerful feature that is actually pretty easy to use! So let’s put the example above in a Polymer web component and apply two-way binding to it. That means we don’t have to press a button to update the firstname and lastname values!

<dom-module id="two-way-binding-polymer">
    <template>
        <h2>Two-way binding!</h2>
        <div>
           <label for="firstNameInput">Whose element is this?</label>
           <input id="firstNameInput" type="text" value="{{firstname::input}}" />
           <input type="text" value="{{lastname::input}}" />
        </div>
        <span>This is <span>{{firstname}}</span> <span>{{lastname}}</span>'s custom element!</span>
    </template>
</dom-module>

<script>
    Polymer({
        is: "two-way-binding-polymer",
        properties: {
            firstname: {
                type: String,
                notify: true,
                value: "Sander" // optional
            },
            lastname: {
                type: String,
                notify: true,
                value: "Rossel" // optional
            }
        }
    });
</script>

There are a few things to notice here. First is the firstname and lastname properties. They’re now objects rather than just empty strings. To use two-way binding we need to set the notify flag. We also need to set readOnly to false, but since that’s a default I haven’t set it explicitly (but now you know there’s such a thing as readOnly too). Also, we must use {{attribute}} syntax for two-way binding. Last, the elements we’re binding to need to have a property-changed event. Since we’re binding to a non-custom element that doesn’t have a property-changed event we can specify the event on which to react ourselves. We do this by using the “property::event” syntax, in this case “firstname::input” and “lastname::input”.
The usage of this element is again very simple.

<two-way-binding-polymer></two-way-binding-polymer>

Conclusion

There’s obviously a lot more to Polymer and web components than what I’ve discussed in this post. At least you’ve got a little look at web components and Polymer in particular.
Now should you use this? As I’ve said before Polymer is still under development. In fact, when I wrote this article a new version came out which had some breaking changes! Next to that Polymer won’t work well (or different) on other browsers. Hopefully that’ll be fixed in different versions (of either Polymer or those other browsers).
That said, web components are awesome and really allow for some modular front-end development! Web components are also something the W3C is looking into standardizing. So I’d be looking out for Polymer, but wait until at least version 1.0 before even considering taking this into production code.

Happy coding!

MEAN web development #3: More Node.js

Welcome back! In my last post we’ve looked at Node.js and added in some Express. You might think that’s that for Node.js, but actually there is just more Node.js stuff I’d like to talk about. So what do I have in store for you this week? We’ll be looking at modules and events, two important aspects of Node.js.

If you haven’t read my previous articles on MEAN and Node.js yet I strongly advice to read them now as this post continues where the previous one left off (although we won’t be using Express in this post).

  1. MEAN web development #1: MEAN, the what and why
  2. MEAN web development #2: Node.js in the back
  3. MEAN web development #3: More Node.js
  4. MEAN web development #4: All aboard the Node.js Express!
  5. MEAN web development #5: Jade and Express
  6. MEAN web development #6: AngularJS in the front
  7. MEAN web development #7: MongoDB and Mongoose
  8. MEAN web development #8: Sockets will rock your socks!
  9. MEAN web development #9: Some last remarks

As always you can find the sources for this blog on my GitHub account in the mean3-blog repository.

And be sure to follow me on Twitter @sanderrossel for more content related to MEAN, Node.js, web development and software development in general.

Modules

In my previous post you’ve already had a brief introduction to modules. Every time you use a require(‘http’) you’re loading the http module. There’s lots of modules, like http, https, net (for socket programming), mongodb, express and just a whole lot more (thousands!). Some come with Node.js, like http, and some need to be added, either manually or through a package manager like npm, like mongodb (which we’ll use in the ‘M post’ of this series!).

Why would you want to create modules? Think of it as a package, a piece of code that is reusable across files and projects. Let’s say you write an awesome bit of code, or just some code you need a lot. You can put this in a module and use it everywhere you like. You can even distribute it (to GitHub, npm, Bower…) so others can use it too!

So let’s build a module. You won’t believe how easy it is! Create a file, myModule.js, and place it in the same folder as your Node.js application. Now in myModule.js simply put the following JavaScript.

exports.hello = "Hello, module!";

Now in your main Node.js application you can use it as follows.

var myModule = require('./myModule.js');
console.log(myModule.hello);

Can you believe it’s that easy!? I’m not entirely happy though. I’m requiring a file in a location. The ./ indicates the folder in which the Node.js file that did the require is located. When we call http, a native module, we don’t need to specify a path though. Alright, but that’s native you might say. But when requiring Express, as we’ve done in my previous post, we didn’t need to specify a path either! Well here’s the thing, when you don’t specify a path Node.js will look for a file with the specified name in the node_modules folder. So if it doesn’t already exist create a folder with the name node_modules and put your myModule.js in it. You can now load it using the following syntax.

var myModule = require('myModule');

That looks better! However, if you’ve installed Express you’ll see that Express has a folder inside the node_modules folder with other folders and files in it. That’s what I want too! Luckily that’s not hard to do either. First we create a folder inside node_modules called myModule. Then we can either create a package.json and put the following JSON in it.

{ "name" : "myModule",
  "main" : "./node_modules/myModule/myModule.js" }

Or we can rename myModule.js to index.js and require will try to get the index.js (or index.node) from node_modules/parameter_passed_to_require/index.js.

So let’s sum that up real quick. Require tries to get the file you passed in as a parameter or, if you didn’t specify the path, it will try to load ./node_modules/parameter_passed_to_require.js or ./node_modules/parameter_passed_to_require/index.js where ./ is the folder of the file that does the require.

Exports

So we can now create the simplest of module and load it using require. But we don’t really understand what’s going on yet. Where did this ‘exports’ thing come from and how can we utilize it?

When using require to get a module require will actually provide you with the exports variable. It’s shorthand for module.exports, so you may use that too. require will simply return the exports object. Basically, when writing a module, imagine the following lines of JavaScript at the top of the file.

var module = {
    exports: {}
};
var exports = module.exports;

So now we can simply use exports and append all kinds of properties and functions to it. For example, let’s create a user module and use it in our application. You can find the source code for this on GitHub.

exports.firstName = null;
exports.lastName = null;
exports.birthDate = null;

exports.getFullName = function() {
    return exports.firstName + ' ' + exports.lastName;
};

exports.getAge = function() {
    // I admit I had to look this one up...
    // http://www.scriptol.com/javascript/dates-difference.php
    return new Number((new Date().getTime() - exports.birthDate.getTime()) / 31536000000).toFixed(0);
};

And now we can use it like this.

var http = require('http');
var user = require('user_export');

user.firstName = 'Sander';
user.lastName = 'Rossel';
user.birthDate = new Date(1987, 11, 8);

var server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(user.getFullName() + ' is ' + user.getAge() + ' years old.');
});

server.listen(1337, '127.0.0.1');

So that’s awesome! But let’s add another user. We might go about it as follows.

var http = require('http');
var user1 = require('user_export');
var user2 = require('user_export');

user1.firstName = 'Sander';
user1.lastName = 'Rossel';
user1.birthDate = new Date(1987, 11, 8);

// Creator of JavaScript.
user2.firstName = 'Brendan';
user2.lastName = 'Eich';
// Don't know his exact birthdate...
user2.birthDate = new Date(1961, 1, 1);

var server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(user1.getFullName() + ' is ' + user1.getAge() + ' years old.' +
    '\n' + user2.getFullName() + ' is ' + user2.getAge() + ' years old.');
});

server.listen(1337, '127.0.0.1');

Now if you run this you’ll notice that this is completely wrong! We can’t have more than one instance of user, so now both users are actually Brendan Eich!

So our module is not very re-usable… But remember that I said that require will just return the exports object? How about if we just set the exports object to a constructor for our user object? The module would now look like this.

module.exports = function User(firstName, lastName, birthDate) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
    self.birthDate = birthDate;
 
    self.getFullName = function() {
        return self.firstName + ' ' + self.lastName;
    };

    self.getAge = function() {
    // I admit I had to look this one up...
    // http://www.scriptol.com/javascript/dates-difference.php
        return new Number((new Date().getTime() - self.birthDate.getTime()) / 31536000000).toFixed(0);
    };
};

Notice that I’m using module.exports! Setting the exports shorthand wouldn’t work here as it is module.exports that is loaded by require! exports is just a shorthand. It references the same object as module.exports, but it is not module.exports. This is a very important difference. If you’re not sure what to use just use module.exports and you’re safe.

So we’re now loading a function with require. How does that look?

var http = require('http');
var user = require('user');

var user1 = new user('Sander', 'Rossel', new Date(1987, 11, 8));

// Creator of JavaScript.
// Don't know his exact birthdate...
var user2 = new user('Brendan', 'Eich', new Date(1961, 1, 1));

var server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(user1.getFullName() + ' is ' + user1.getAge() + ' years old.' +
    '\n' + user2.getFullName() + ' is ' + user2.getAge() + ' years old.');
});

server.listen(1337, '127.0.0.1');

The code became a little cleaner, but more importantly, I can now have two instances of the user object!

And of course you can require in modules too. Try putting the following in a module.

var http = require('http');

exports.startServer = function() {
    var server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Server was started from module!');
 });

    server.listen(1337, '127.0.0.1');
}

And to try that out.

require('start_server').startServer();

Events

Another important aspect of Node.js is Events. If you’ve worked with .NET, and especially WinForms, you should be familiar with events already. In JavaScript events are usually implemented as callbacks, a function that is called when a certain action completes. Node.js has a special module that handles events.

Let’s implement a basic event.

var http = require('http');
var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();

emitter.on('request', function(url) {
    console.log('requested ' + url);
});

var server = http.createServer(function (req, res) {
    emitter.emit('request', req.url);
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('url logged to console.');
});

server.listen(1337, '127.0.0.1');

So as you can see we start by requiring the events module. We then create a new instance of the EventEmitter class. To create an event simply use the on method and pass it the name of the event and a function that should be executed when the event triggers. To actually trigger the event call the emit method and pass it the name of the event and the event data.

It is totally acceptable to add multiple handlers to the same event.

var http = require('http');
var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();

emitter.on('request', function(url) {
    console.log('requested ' + url);
});

emitter.on('request', function(url) {
    console.log('second listener, received request ' + url);
});

var server = http.createServer(function (req, res) {
    emitter.emit('request', req.url);
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('url logged to console.');
});

server.listen(1337, '127.0.0.1');

It’s also possible to handle an event only once using the once method.

emitter.once('request', function(url) {
    console.log('one time listener, received request ' + url);
});

And you can remove listeners as well using the removeListener function. To remove a listener you need to pass in the listening function, so we cannot start listening using an anonymous function like I did up til now. So in the following example I declare a function, add it to my emitter and then remove it after three server requests.

var http = require('http');
var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();

var removableEvent = function(url, counter) {
    console.log('this event will be removed in ' + counter + '...');
};

emitter.on('request', removableEvent);

var counter = 3;
var server = http.createServer(function (req, res) {
    emitter.emit('request', req.url, counter);
    counter--;
    if (counter === 0) {
        emitter.removeListener('request', removableEvent);
    };
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('url logged to console.');
});

server.listen(1337, '127.0.0.1');

And of course any event emitter can have as many events as you want and trigger them in different places.

var http = require('http');
var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();

emitter.on('request', function(url) {
    console.log('requested ' + url);
});

emitter.on('message', function(message) {
    console.log('Received message: ' + message);
});

var server = http.createServer(function (req, res) {
    emitter.emit('request', req.url, counter);
    emitter.emit('message', 'Received request for ' + req.url);
 
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('url logged to console.');
});

server.listen(1337, '127.0.0.1');
emitter.emit('message', 'Server started and listening on 127.0.0.1:1337');

So as you see working with events isn’t very difficult, you just have to know how it works.

This was my third article in the MEAN series and the second one on Node.js. There’s a lot to say about Node.js, in fact I’m not quite done yet! We’ll look at more Node.js goodness in upcoming articles. I do want to move on to the other letters of MEAN as well though. So for my next article I’m going for either M (MongoDB) or E (Express.js). Both require more Node.js. So if you have any preference let me know! M or E, most votes wins. For no votes or a tie I’m simply going to pick one myself.

And again I’m going to recommend some books, just in case you missed them in my previous articles. Be sure to get Node.js Succinctly from Syncfusion, it’s free and the subscription is totally worth it since they have lots more free ebooks!
For a bit more in depth Node.js knowledge I can recommend Mannings Node.js In Practice, Node.js In Action or Getting MEAN With Mongo, Express, Angular, And Node. They’re not free, but Manning provides value for your buck!

That’s it for this week. I hope to see you back next week for either MongoDB or Express.js (be sure to let me know what you want!).

Stay tuned!