Preparing Your Angular 1 Code For Angular 2 (Part 2)
This post is Part 2 of a series of blog posts where I’ll convert an Angular 1.x project to Angular 2. In Part 1, I upgraded the Angular client to use the latest guidelines in the John Papa Angular Style Guide.
Node.js has improved by leaps and bounds since I first wrote the Phone Cat MEAN project. If you’re not familiar, the tutorial on the AngularJS 1.x site takes you through the process of writing an application for viewing a catalog of cell phones and their details. Like many others, I did the tutorial when I was first learning Angular, but I took it further and turned it into an MEAN stack (Mongo, Express, Angular, Node) project.
Since that initial project, one of the biggest changes to Node has been support for ES6 (or, as it was renamed, ES2015). Using the latest ES6 syntax has the potential to simplify a lot of your code.
In this blog post, I’ll upgrade the Node.js server to use ES2015.
What do I need to write ES2015 in Node.js?
The latest versions of Node support many of the features of ES2015 natively. If you want to use an ES2015 feature that is not on that list, you can install Babel as a dependency to support additional features with on-the-fly transpilation in Node.
import
and export
are two of the features that Node doesn’t natively support. To support these features, I used npm
to install and save babel-register
and babel-preset-es2015
. Then I required babel-register
in my Node.js project and configured my .babelrc
file to use the es2015
preset.
What ES2015 features work best in Node.js?
The ES2015 (ES6) features that I used in this project were:
import
– the ES2015 version of therequire()
statement that every Node programmer is familiar with. It allows you to import all or portions of another file.export
– the ES2015 version of themodule.exports
command. Files can now have multiple exports and default exportsArrow
functions – a simpler way to create anonymous functions that have the same lexicalthis
as the outer scope. That means you don’t have to wrapthis
to call it from within the anonymous function.Promises
– reduce the headaches of callback helllet
– block scoped variables`${Template} strings`
– interpreted strings that reduce the need for string concatenation
I’ve seen examples where people used Class
but I didn’t think this project warranted it.
What were the steps to upgrade the code to ES2015?
- Use NPM to install the following dependencies:
babel
babel-preset-es2015
babel-register
body-parser
compression
express
mongoose
serve-static
morgan
– dev onlynodemon
– dev only
- Create a
.babelrc
file and set the preset toes2015
- Create a new Heroku app and attach MongoLab
- In your Heroku app, open Settings -> Config Variables and reveal the variables
- You should see a variable called
MONGOLAB_URI
- This variable holds your MongoLab username, password & URL in the format of
mongodb://<username>:<password>@<sub-domain>.mongolab.com:<port>/<database>
- You can use this connection string to connect to the MongoLab database, if you are running your Node server on your local computer. BUT make sure you do not commit this string to your GitHub repo. Committing this string to your repo makes it public and people have been known to steal passwords this way.
- Rather than use this string directly in your code, it’s recommended that you use it as an environment variable in your code, as I have done (see
db -> index.js
). Then you can run your program from the command line like this:$ MONGOLAB_URI=<connection string> node index.js
Since Heroku already has this variable set up, it will run your Node.js server correctly, if you use the environment variables in your code.
- Install the Heroku Toolbelt and use it on the command line to connect the git directory to Heroku
- Use the MongoLab interface or MongoDB’s CLI to add data to MongoDB
- The inserted data was originally in the JSON files in the
app -> phones
directory
- The inserted data was originally in the JSON files in the
- Update the server code using this Git Repo as an example
- I used that repo as an example but rather than use the resource pattern shown there, I wrote my own endpoints using standard Express functions
- I ended up with the following directory structure:
/ -- index.js -- server/ ---- index.js ---- api/ ------ index.js ------ phone.js ------ phones.js ---- db/ ------ index.js ---- models/ ------ phone.js ------ phones.js ---- static/ ------ index.js
- Update the client to use
$resource
and connect it to the updated server - Deploy the code to Heroku
How does ES2015 improve NodeJS code?
The full project is too long to walk through in this post but an example should suffice:
import { Router } from 'express'; import Phones from '../models/phones'; let router = Router(); router .get('/', (req, res) => { Phones .find({}) .then(phones => res.json(phones)) .catch(err => res.send(err)); }); export default router;
In this example, I’ve used a number of the ES2015 (ES6) features. I’m using import
to import the Router portion of the Express library and the default portion of the Phones model. At the bottom of the file, I export
the router object as the default so that it can be imported into the API.
In the .get()
, I’m using several Arrow functions as a substitute for the more verbose anonymous functions. The change in the lexical this
wasn’t necessary, but the shorter code is appreciated.
The Phones model was written with the Mongoose library. Mongoose allows you to attach ES2015 promises. Here, I’m using the promise to handle the success and failure results with nice, tight Arrow functions.
The final code is available here. You can see a working copy of the website here.
Keep checking back for additions to this blog series. In upcoming posts, I’ll be taking a look at ng-forward
, ng-upgrade
and Angular 2.