Coursera Full Stack Web Development Capstone Project

A couple of days ago I finished my capstone project for the Full Stack Web Development specialization on Coursera. It marks the end of the 6-course specialization about Bootstrap CSS, AngularJS and NodeJS.

The Assignment

The assignment itself is simple:

Build a web application with the tools taught in the course (Bootstrap CSS, AngularJS, NodeJS, MongoDB).

Everybody has the free choice what to implement, however it should be a small app as it must be implemented during a short period of time. I decided to implement a message board where users can create boards and post messages (more below).

The Schedule

The capstone project takes 8 weeks in total, while only 2 or 3 weeks are dedicated to actual coding. Each weeks has about 3 hours of workload. So you can spend approximately 9 hours to coding – but you will definitely spend more time!

Week Topic Assignment
1 Ideation
2 Ideation Report Report (PDF, 2 pages) about your idea
3 UI Design and Prototyping
4 UI Design and Prototyping Report Report (PDF, 2 pages) with UI mockups
5 Architecture Design and Software Structure
6 Architecture Design and Software Structure Report Report (PDF, 3 pages) with architecture, structure, REST URLs, data model
7 Project Implementation and Final Report
8 Final Submission and Report Report (PDF, 2 pages), code on GitHub, running app on IBM Bluemix

The Workload

You will spend most of your time for coding, but there will also be a huge amount of time you will spend on organisational tasks. Those tasks might take a lot of time:

  • Making a GitHub project including README.md, .gitignore and so on
  • Setup a Travis CI build
  • Deploy to IBM Bluemix (read tutorials, write a .cfignore and manifest.yml)
  • Do all dependency management
  • Install and configure MongoDB
  • Manage different configs for you local development and IBM Bluemix

While all of those tasks are absolutely necessary for every project setup, they can easily take up some hours nevertheless. This melts down your coding time.

My Project

I called my project MEBO which simply stands for Message Board. It’s a small application where users can create boards and post messages on them. Every who know the link to a board can access it and edit all messages. There’s no login or so. You can find the project on GitHub: https://github.com/tuhrig/mebo.

Lessons Learned

  • Make it small! Pf course, everybody wants to make this super fancy application with its own user management, administration view and all kinds of features. But make your life easy and do what’s needed to demonstrate your skills.
  • Start early with the deployment and integration to IBM Bluemix. No matter how well your project is implemented, if it doesn’t run on IBM Bluemix (or anywhere else) where I can see it, you will not pass the assignment. Get things up and running from the beginning.
  • Let it looks nice. The first impression is very important. If your project looks nice and your GitHub project has a README.md, your’re on the right path.

Best regards,
Thomas

Coursera Full Stack Web Development Course Review

During the last 6 months I did the Full Stack Web Development course on Coursera. Since I’m currently about to finish the course by implementing my final capstone project (https://github.com/tuhrig/mebo), I wanted to share my thoughts about the course and its pros and cons.

About the course

The Full Stack Web Development course consists of 6 single courses. Altogether, they make up the complete course which Coursera calls a specialization.

  1. HTML, CSS and JavaScript (3 weeks)
  2. Front-End Web UI Frameworks and Tools (4 weeks)
  3. Front-End JavaScript Frameworks: AngularJS (4 weeks)
  4. Multiplatform Mobile App Development with Web Technologies (4 weeks)
  5. Server-side Development with NodeJS (4 weeks)
  6. Full Stack Web Development Specialization Capstone Project (8 weeks)

It’s possible to take single courses, but of course it’s recommended to take all of them and do them one after another in the given order.

The complete specialization takes 27 weeks and costs 70 € per course, so 420 € in total.

HTML, CSS and JavaScript

This course thoughts the basics about HTML, CSS and JavaScript. It was made for beginners, so if you have a little knowledge of those topics you will probably be board. On the other side, if you have absolutely no knowledge about this HMLT, SSC and LavaScipting, you will have a hard time to learn everything in just 3 weeks. Because that’s how long the course will take.

IMHO: I don’t recommend this one. If you know HTML, CSS and Javascript you won’t learn anything from the course. And if you are absolutely new to those technologies, the course is far too short.

Front-End Web UI Frameworks and Tools

This course focuses on Bootstrap CSS. Although Bootstrap CSS isn’t too complicated, a lot of people don’t understand the principles behind it (e.g. the grid system with its rows and columns). So even if you used Bootstrap CSS before, this course will help you to understand things better.

IMHO: I recommend this one as it really helps to better understand one of the most popular UI frameworks right now.

Front-End JavaScript Frameworks: AngularJS

What the second course was for Bootstrap CSS, this one is for AngularJS. And again, if you know AngularJS there will be nothing new to you. But if you are new to AngularJS this course will find the right tempo to give you a good first glance. However, the course is not really up-to-date with AngularJS’ latest version.

IMHO: I recommend it, as this course gives you a good introduction to AngularJS.

Multiplatform Mobile App Development with Web Technologies

This course is made up around the Ionic Framework for mobile apps. If you are interested in building mobile apps, this course will teach you one out of a thousand possibilities to do this. I think the Ionic Framework is not the worst way to make mobile apps, however the course is still very opinionated and has a very small focus.

IMHO: Out of all 6 courses, I can recommend this one at least. Ionic might be good for some use cases, but the example app made in the course doesn’t benefit from it in any way. It’s just the very same app as made before. Making everything responsive would be a much better approach. This course also relies heavily on installed software like Ionic itself and Android or iOS simulators. If one of those pieces of software don’t run on your device, you are screwed. It took me hours to get the Android simulator to run, before I switched to the iOS simulator which also took me hours.

Server-side Development with NodeJS

This course is about NodeJS and MongoDB. Although the architecture of the example app of the course is terrible (they make database queries in the REST controllers!), the course gives a nice introduction to server-side JavaScript. Both technologies – NodeJS and MongoDB – are state of the art.

IMHO: I can recommend this one to get started with NodeJS and MongoDB, but also to see some draw backs of those very hyped technologies.

Full Stack Web Development Specialization Capstone Project

At the end of the course, everybody must implement a final project. The project should show the learned skills and should – of course – use technologies thought in the course. So you are forced to get your hands dirty and write some own code.

IMHO: This part of the specialization is very interesting, but has some pitfalls, too. It’s important to choose the project idea wisely. The course only takes 8 weeks from which only 2 are dedicated to actual programming. So whatever you implement, it must be something small.

Special note: To complete the course, you must deploy your project to IBM’s PaaS Bluemix for which you will get a test account. As I worked with AWS and some other DevOp technologies before, this wasn’t too hard for me to do. However, Bluemix is a terrible plattform. If you are not familiar with PaaS, plan some extra time to get things working. The course will not prepare you for that in any way.

How Coursera works

Before you take a course at Coursera, you should first understand how the plattform works: Courses on Coursera are mode up of online videos, text and PDFs, exercises and assignments. It’s up to the teacher of the course is laid out.

Every course runs regularly at some specific date and will end at some specific date. This means a course might start every 2 months beginning at the first of the month and ends 4 weeks later. You must (!) take the course at this period of time. It’s just like a physical class you would take at school or university.

Most courses require assignments to complete them. This means there will be some exercise at the end you must fulfil and upload the solution. Most assignments are peer-graded which means that you must review your classmates and you will be reviewed yourself by them.

At the end, you will get a certificate with a lot of buzzwords for this specific course.

IMHO: Coursera is nice, but it’s not the same as a real physical class at university. Especially the peer-graded assignments are problem. Some people tend to criticize the most odd things, while others just give you the point without even looking at your work. It’s completely up to you how serious you take it.

What I learned

Things I liked to learn

Things I didn’t like after learning them

What I missed

What I missed completely during all 6 courses was unit testing. None of the courses teach anything about testing, neither in the front end (Jasmine, Protractor) nor in the backend (Mocha, Sinon).

More

Best regards,
Thomas

Java vs. JavaScript Build Tools

When you come from a Java background like I do and you take a look at JavaScript build tools, the sheer mass of tools is overwhelming.The eco system is evolving very fast with new tools coming up every couple of months. Below, I tried to give a comparison between Java build tools and their equivalent in the JavaScript world.

Preface

The list below aims to show similarities – not differences. Of course, every tool has its own set of features and individual strengths. The tools on the left are not the very as the tools on right, just for another software stack. However, to see some similarities might help to better understand how the JavaScript world works.

Runtime

java nodejs
  • Platform where all tools will run on
  • Executes scripts, tests, etc.

Task Runner

gradleant gruntgulp
  • Executes scripts and orchestrates tasks
  • Copy files, uglify, minify, package…

Package Manager

maven bower300
  • Dependency Management
  • Versioning

Test Runner

junit karma
  • Tests
  • Test Suits

Mocking/Assertion Library

bildschirmfoto-2016-11-14-um-09-17-07 Jasmine
  • Assertions and expectations (assertThat(1 + 1, is(2)))
  • Mocks and stups

Best regards,
Thomas

AngularJS provider and app configuration

AngularJS provides 3 different ways to create a service:

Factory

A factory is a well known pattern in software development. It aims to create a certain object, in this case a service. In AngularJS this is simply a function which returns an object with methods. In my opinion, this is the cleanest way to create a service in AngularJS.

Service

Another way to create a service is a mechanism called “service”. In this case, your service is a function which has other functions attached to this. It is the shortest way to create a service in AngularJS. However, it sometimes becomes confusing when you need to refer to your own functions using this.

Provider

The last way to create a service, is a provider. A provider fulfils a certain interface and implements a method called $get. This method returns a function which in turn returns the service object. So by calling $get on a provider, you will receive a service factory. This is obviously the most verbose way to create a service.

So why should I use a provider?

So if a provider is the most verbose method you have to create a service, why should you use it at all? To answer this question, it’s important to know that no matter which way you use – factory, service or provider – AngularJS will always create a provider for you internally. That’s why you will sometimes see an error message like this:

When an AngularJS app is started, it has a certain “boot-order”. From the perspective of a developer, it looks like this:

After you defined your application/module, you have a configuration phase and a run phase. The difference between both phases is the service instantiation. During the config phase, the providers have been registered, but they have not been called yet! During the run phase all providers have been called and their services have been registered. This means that you cannot inject any service during the config phase and that you cannot inject any provider during the run phase. Though you can use the config phase to configure your providers and it’s service.

Let’s take a look at the AngularJS UI-Router for an example. If you don’t know it, you can find the documentation at https://github.com/angular-ui/ui-router/wiki/quick-reference.

The AngularJS UI-Router provides both, a provider called $stateProvider as well as a service called $state. The usage would look like this:

By using a provider we have the possibility to configure a service before the AngularJS application runs. We can setup things in advance which can be constant during our application lifecycle. If you need something like this, go with a provider. Other wise use a factory or service.

More

Best regards,
Thomas

Reusable AngularJS form components

Whenever you build software, you want to create reusable and independent components. In the world of user interfaces, those components are often called widgets. Here’s an example how we can achieve this with AngularJS.

An example

Let’s say we have an online shop where a customer can make an order. To do so, the customer must provide some data, in particular an invoice address and a delivery address:

Both, invoice address and delivery address, look exactly the same. They are an example for UI elements which can be bundled in an reusable component.

An AngularJS UI component

With version 1.5 AngularJS introduced the concept of a component. AngularJS’ components are a syntactic short-cut for common directives. So if you use an AngularJS version prior to 1.5, you can achieve the very same behaviour with directives – just with a little bit more code.

An AngularJS component for our address example could look like this:

The my.address.html template would look like this:

If we got this two pieces of code, we can use our brand new component:

Pitfalls

Although our example is still very simple, there are already some pitfalls you need to be aware off.

  • While we have named our component myAddress (camelCase) in our JavaScript code, we need to name it my-address in our HTML code. Otherwise the component will not be recognized.
  • We used the controller-as syntax to name our OrderController just controller. However, inside the template of our component, we must refer to the controller as $ctrl by default.
  • We bind our data to a property which we called address. We can name this property totally as we like, but we need to make sure that we refer to this property from inside of our template: ng-model="$ctrl.address.city"
  • We have used a bi-directional binding using the = operator. So if the model changes inside our component (because the user has entered some text in one of the input fields) it will affect the same object inside our parent controller. Otherwise we wouldn’t be able to access the data.

Accessing the data

Now that we have successfully added our component to our page, we also want to use the data of the delivery and invoice address. Doing this in our parent controller (OrderController) is quite easy:

The result would look like this:

Note that invoiceAddress and deliveryAddress is nested in an object called data because we set-up the component like that:

Form validation

Another pitfall which might be a little bit tricky is form validation. Let’s start with an example again. First, we add form validation to our initial example where we don’t use any components:

This is an example of a very simple form validation build with AngularJS build-in functionality. If the one of the input fields (firstName or lastName) is invalid, a certain CSS class will be applied to mark the field as visually for the user. If we do the very same for our component, we will come to a problem: In order to apply the CSS class with ng-class we need a reference to the form:

Since we want to make an independent component, we don’t want the component to know something about the form in which it is included. This would break encapsulation and we couldn’t reuse the component wherever we want. But we cannot put the component in its own form, because HTML doesn’t allow to nest form. So if we would package our component into its own little form, the browser would ignore and remove it:

bildschirmfoto-2016-10-31-um-09-15-07

The solution is to use ng-form instead of HTML’s form. It will enable AngularJS’ form validation, but will not be touched by the browser. Our component will look like this:

Plunker

You can see the complete working example here:

https://plnkr.co/6UyqVn

More

Best regards,
Thomas

Booting an AngularJS application

Every back-end application has a boot process. Services must be instantiated, connections must be established and configurations must be loaded before the application is ready. How can we do something similar for an AngularJS application?

ng-app

The typical way to start an AngularJS application is to use the ng-app directive on an HTML element (mostly body). Using ng-app Angular will do the bootstrapping of your application automatically. This is perfectly fine for most cases. But if we need more controller of the bootstrap process of Angular, we can do thins manually.

Manual start-up

Instead of using ng-app we can write a piece of JavaScript code to start our application:

Now we are able to start our application manually and to do initialization tasks!

Task 1: Loading data from the backend

A typical start-up task would be to load some initial data (for example a configuration) from the back-end. The code below will make a GET-call to the back-end in order to retrieve some configuration. After the GET-call has finished the application will be started. This makes sure that we have all data up-front.

Task 2: Going to an initial state

Most AngularJS applications have different states. E.g. a view of the user profile (/app/user), a view of the private messages (/app/messages) or simply a home screen (/app/home). Before we start our application, we want to navigate to the correct state. While there are many ways to achieve this, here is an approach how to do it by using an bootstrap script:

The method angular.bootstrap() will return the injector of our application. We can use this injector to access all services of our application (including the routing). In the example below, we assume that we save every state in the session storage of the browser. So we can always look in the session storage to finde the last state where the user has been. If the user now reloads the page in his browser, the AngularJS application will start again. The application will look in the session storage, find the LAST_SAVED_STATE and go to it. Note that we could also use another type of storage (maybe cookies) to persist the state.

Where to put the start-up script to

We usually create one start-script per application, e.g. my.app.bootstrap.js. We code shown above is wrapped into an IIFE and included as the last dependency into our HTML code:

Best regards,
Thomas

More

AngularJS Intensive Workshop by Robin Böhm/Symetics GmbH

Last week I attended an AngularJS Intensive Workshop by Robin Böhm/Symetics GmbH. Symetics is the company behind www.angularjs.de and provides consulting and training all around JavaScript, AngularJS (1/2) and TypeScript.

original-93d514756bd905adaf57c9033f69be39

The location

The 3-days workshop was located in the UNPERFEKT Haus in Essen. The UNPERFEKT Haus is an open space for artists, students and musicians and provides rooms, WLAN and a lot of creative environment. It was a really great location for the seminar and we all felt comfortable.

The trainer

Our trainer was Robin Böhm who is the CEO/founder of Symetics GmbH. He works as a freelancer and does consulting, in-house training and workshops all around web technologies like AngularJS. During the 3-days he provided a lot of information and made a really intense workshop. However, the atmosphere was always relaxed and Robin was open for discussions and questions – even during the lunch break.

The workshop

The workshop was divided into two parts: (1) a round trip about JavaScript and (2) a dive-deep on AngularJS. It was a good mix of presentations and hands-on sessions on a prepared sample project. Robin managed to cover an huge amount of topics:

  • components vs. directives
  • routing (with the new router from AngularJS 1.5)
  • testing (with Jasmine)
  • the promise API
  • build tools
  • books to continue

Robin also tried to give us an outlook on AngularJS 2 and how we can prepare our current projects for it.

My opinion

Actually, there wasn’t much I didn’t like. The workshop covered all relevant topics and gave us a lot of useful insights into AngularJS and related stuff.

I can really recommend it!

It was fast, well prepared and very practical (we wrote code for about 1/3 of the time). The group was medium-sized, maybe 14 people (mostly Java developers). The only downside was that Robin sometimes provided to much detail on a particular topic. I’m more comfortable with staying by the underlying concepts of a technology and dive into the nitty gritty details when I’m working on it.

I’m looking forward to the next workshop! Thanks!

Thomas.

More

Use ranges with ngRepeat

ngRepeat

Angular’s ngRepeat directive provides a simple way to iterate over collections to produce HTML dynamically. You probably know it when you have ever worked with lists or arrays in your Angular app:

Drawbacks

However, there is a small drawback when working with ngRepeat: You can only iterate over collections of the current scope. Loop definitions (like a typical for-loop) are not supported. This means you cannot to something like this:

The solution

But there is a simple trick to build a workaround for this. If you use a library like Lodash.js or Underscore.js the trick becomes even more simple: As ngRepeat requires a function on the scope, we just provide such a function!

That’s all we need. If we append Lodash/Underscore to our scope, we can use the library within our partials. This might looks like this:

Keep in mind

With great power comes great responsibility. When we append Lodash/Underscore to the Angular scope, we not only pollute the scope with more functionality, we also put program logic from the controller to the partial. And we shouldn’t do that! A partial should be as easy as possible and all application logic should be in the controller or services. But this is also a trade-off, as this solution might be fine for small and simple problems.

Best regards,
Thomas

Testing AngularJS directives with Jasmine

Directives

AngularJS provides a mechanism called directives. Directives are markers in our HTML which Angular will read and use to inject some special behavior to our HTML code. As this sounds a little bit theoretically, let’s look at an example:

In this example the directive ng-model is used which will bind the value of the input field to a field called name in the current $scope. This directive already comes with AngularJS, but it’s also possible to write your own directive. That’s what we do right now.

A custom directive

In order to have an useful example to test, we write our own directive. In this case we will use a directive which will listen for an “on-enter-event” on an element. It looks like that:

And you use it like that:

The example creates a directive called onEnter which you must refer as on-enter in your HTML. The directive takes a single argument which is a function in the current scope (e.g.: showNotification()). So when we type in your input field and press enter the directive will be called. It will get an event and it will check if the event comes from “enter” or another key. If it was an “enter”, the directive will call our method. Looks good? So let’s test it.

Testing

Testing this directive isn’t a big thing, but it will bring us the evidence that it works like we expect it. A Jasmine test might look like this:

What does the test do?

The test does the following: First we load the module which contains our directive and inject AngularJS’ $rootScope and $compile service. As a directive is attached to the HTML, we need to take some HTML and compile it with AngularJS in order to make the directive work like in a real life scenario.

Now we create our actual test case. First we create a spy function (jasmine.createSpy('test');) and attach it to our scope (which is simply the root scope). This function should be called by the directive if it works correctly. Now we create some HTML which uses the directive and compile it. The last thing we need to do is to create an on-enter-event and fire it up on the compiled element. This simulates the user pressing enter.

Last but not least we verify that the on-enter directive worked and has invoked our test function on the root scope.

What the test doesn’t do

The test only verifies the happy path. It tests if the function is called when enter is pressed, but it doesn’t verify the opposite: Is the directive only listening on “enter” or will it also call our function if another key is pressed? However, implementing this test shouldn’t be a big thing now.

Best regards,
Thomas

More

https://docs.angularjs.org/guide/directive

Two-way binding for URL parameters in AngularJS

Single page applications (maybe with AngularJS?) are the new cool kid in town. So are URL parameters which are an essential part of how single page applications work. URL parameters hold the current state of an application and enable to open the application in this state (e.g. with a so called deep link). That’s how the look like:

In this example, showAll=true and filterByName=Thomas are the URL parameters. The hash (#) divides the URL into two parts: a part which goes to the server (before #) and a part which stays on the client (behind #). This is the so called anchor part which holds our URL parameters. So this part of the URL is purely for our AngularJS client!

Two way binding

Two way binding means that bind a parameter of our URL (e.g. filterByName) to a parameter of the controller (let’s say it has the same name: myController.filterByName). To achieve this, we need update our controller if the URL parameter changes and we need to update our URL parameter if the controller changes. That’s what two way mean – controller to URL, URL to controller.

Controller >> URL

Let’s start with the first way: controller to URL. Everytime a property of the controller changes, we want to update the corresponding property of the URL. To do this, we use Angular’s $watch method (see https://docs.angularjs.org/api/ng/type/$rootScope.Scope). The method $watch allows to watch a value and do something if it changes. Exactly what we want! The code is pretty straight forward:

This code will do the following: It will create a watcher which listens on the property filterByName of our controller. If the property changes, we get the new value and set it to the URL (by $location.search("filterByName", newVal);).

(By the way: To use the URL parameters we use a service called $location provided by Angular! That’s the default way to access the URL.)

URL >> controller

Now we only need the way back: URL to controller. As you might guess, we just use another watcher for that. But in this case we use Angular’s $on. This looks like that:

What $on does is simple: It listens for events, e.g. the $locationChangeSuccess event, which is thrown after the URL has changed. If this happens, we use the $location service to read the value from the URL and assign it to our controller.

Put it to a method!

We already have achieved what we wanted: we have a two way binding between our controller and the URL. One last thing we might do right now, is to put this into a nice method we can reuse:

If the property of our controller changes (e.g. because the use inputs data) the URL will change. And if the URL changes (e.g. because we clicked on a link) the controller will change. We have a two way binding between controller and URL!

Best regards,
Thomas

Links