Building the To Do front-end using AngularJS
Update (7/3/18): Fixed webpack.config.js for Webpack 4.
This series is meant as a companion to the JavaEE series where we built a back-end service. In this series, we’ll build an AngularJS front-end that ties into this back-end service. As such, it is required to be running while going through this series. Also, please note that this is going to cover AngularJS. AngularJS should not be confused with Angular which is the newer framework that will be covered in another series in the future.
We will be using Node as a build-tool for our web application. If you don’t already have it installed, please do so now. I’d highly recommend using nvm to install node. If you haven’t heard of nvm, you can read a brief introduction to it by clicking here.
Initial setup and Webpack
The first thing we’ll need to do is create our project folder and initialize it. After you create the folder, navigate to it and run:
npm init
It’s safe to press enter for all of the prompts. This will generate our basic package.json file. Now we need to install some build dependencies:
npm install -D webpack webpack-dev-server
Webpack is a build tool that takes all of your web application source files, processes them, and bundles them together. It’s very extensible and popular among web developers because it can do so much for you. We’ll barely scratch the surface of what it can do in this series.
Webpack-dev-server is a useful tool that, when running, watches all of our source files for changes. If it detects anything has changed, it will re-generate the bundle file. It also hosts the project on a small HTTP server and will automatically refresh your browser when the bundle file changes.
Once npm is done installing those dependencies, we’ll want to create our webpack.config.js file. Do that and paste the following into it:
var config = { entry: './src/index.js', output: { filename: 'bundle.js' }, devtool: 'source-map', optimization: { minimize: false } }; module.exports = config;
This is a very basic Webpack configuration file. We’re telling it that our main entry file is index.js located under the src folder (we’ll create that in a moment) and we want all of the javascript files in our application bundled together in “bundle.js” which will be located in the same folder as the config file. The “devtool” option tells Webpack to generate a source-map. Source maps will allow us to see and interact with the original source code in the browser. Without these, it would be difficult to debug in case anything goes wrong. The nice thing about source-maps is they’ll be picked up automatically if they exist so this is the only thing we need to do.
Let’s create an index.html file with the following contents:
<html> <head> <script type="text/javascript" src="bundle.js"></script> </head> <body> Hello Jimmy! </body> </html>
All we’re doing here is including our bundled javascript and printing “Hello Jimmy!” to the screen. Now create an “src” folder and then create an “index.js” file inside of it. Add the following to it:
console.log("Hello");
This will print “Hello” to the developer console in the browser.
Go back to package.json and change the “scripts” section to contain:
"watch": "webpack-dev-server --port 3000"
This will allow us to easily start the webpack-dev-server on port 3000 by invoking the “watch” script. Let’s do that now:
npm run watch
It may take a second or two to start. Once it’s running you’ll see a message similar to “Project is running at http://localhost:3000/” with some other stuff after it. Go ahead and open http://localhost:3000 now. You should see “Hello Jimmy!” on the screen and if you open the developer console you should also see “Hello”.
AngularJS
Now that Webpack is installed, let’s add AngularJS to our project. Do that by running the following at the command-line:
npm install -S angular angular-route
This will install both AngularJS and its routing component. There are alternatives to angular-route out there, but we don’t need anything fancy for our application. Angular-route will allow us to change the UI and route to different parts of our application based on the URL.
After those are installed, let’s revisit index.html and change it to this:
<html ng-app="todo"> <head> <script type="text/javascript" src="bundle.js"></script> </head> <body> <div ng-view></div> </body> </html>
You’ll notice we added a “ng-app” attribute to the “html” tag. This tells AngularJS that we want to initialize the “todo” module once everything is ready. The other thing you may notice is the contents of the “body” tag changed to a div with the “ng-view” attribute. This attribute tells AngularJS to inject our templates into this part of the DOM.
Change index.js to the following:
import angular from 'angular'; import 'angular-route'; import routes from './routes'; import homeComponent from './home.component'; var app = angular.module('todo', ['ngRoute']); app.config(routes); app.component('home', homeComponent);
Webpack allows us to use ES6 syntax in our source. “import” is part of ES6 and pulls other files into our project. Ultimately, everything we include will be bundled together in that bundle.js file we defined in the webpack.config.js file.
“angular.module” will tell AngularJS to register the “todo” module and that it depends on the “ngRoute” dependency. The following lines will register the “routes” configuration and define a “home” tag with AngularJS. An AngularJS component allows us to “extend” HTML by creating our own DOM elements, such as “<home>” and add functionality to it.
Let’s define our routes by creating a src/routes.js file with the following:
export default function($routeProvider) { $routeProvider.when('/', { template: '<home></home>'}); };
In order for a module to be picked up by an “import” statement, we need to export something. This is what “export default” will do. In this case, we’re exporting a function that will define our “root” route. When the browser accesses the root URL of our application AngularJS will render “<home></home>” inside of our “ng-view” tag in index.html. We haven’t yet defined what “home” will do, but that’s next.
Create a file, src/home.component.js with the following contents:
var controller = function($scope) { $scope.$onInit = function() { console.log("$onInit"); } }; export default { templateUrl: 'home.html', controller: controller };
Here, we’re defining two things: a “controller” and an object containing configuration information for the home component. The configuration object for the component tells AngularJS to render the contents of home.html in place of the “<home>” tag we defined earlier. The contents of that file are then tied to the controller we defined. The controller doesn’t do much. All it does is print something to the developer console when it’s initialized.
Create the file “home.html” at the root of the project with the following contents:
Hello world! I'm home!
If you’re still running the webpack-dev-server you should see that your screen automatically updates and renders the text “Hello world! I’m home!” and your developer console should say, “$onInit”.

You may have to stop and restart your webpack-dev-server as it currently isn’t configured to monitor HTML files for changes.
That’s it for this post. It was a lot to cover, but we have the foundation of our AngularJS project in place to make some real progress in the next few posts.
Source code to the entire series is available here:
I tried your example and I am Getting the following error:
angular.js:138 Uncaught Error: [$injector:modulerr] Failed to instantiate module todo due to:
Error: [$injector:unpr] Unknown provider: e
Can you please suggest me the solution for this
Hi Akhilesh! The problem lies with the newer version of Webpack. For now, please use older versions. Instead of of “npm install -D webpack webpack-dev-server”, you can type “npm install -D webpack@3.10.x webpack-dev-server@2.10.x”. You may also need to remove your node_modules folder before running that command (I had to). I’ll update this blog post to use the newer version of Webpack as soon as I can.