Note: The first part of this tutorial will be more informative and a general overview in the technologies used and what you need to know. The second part will be a tutorial where you can get a simple app up and running written in Angular.
A couple of months ago I decided to switch over to making front end web applications (single page, using a JS framework). Up until then the majority of my experience had been in developing for Android. Web is a much larger ecosystem than mobile, and it can be a bit daunting at first as there are many more ways to go about completing a feature/task. There are also many more components involved in getting it setup, whereas with Android you now have Android Studio at your disposal, so you can start working on an Android application within an hour.
On the other hand, there is one great thing about coming over from Android—you are completely used to dealing with varying screen sizes and compatibility issues with different vendors and OS versions! So the discomfort and annoyance of supporting different browsers and versions will have you feeling completely at home.
This post will help you map your knowledge of Android to the equivalent in web. It does have a fairly focused view on the Angular framework, given my experience and its current popularity spike.
Overview: The Big Picture
Angular, while still the most popular choice, is actually undergoing a huge refactor which will cause some applications to not work as intended when Angular 2.0 releases in a year or so. It’s not so much an update as a complete rewrite! As a web developer, you quickly learn not to rely solely on the framework.
Essentially, to learn web you can’t just purely get by with your understanding of the framework. You will need to have a good understanding of the language behind it all. It will obviously take time to learn the language and get better at it, but there are a few concepts that differ enough from Java that they are important to know/understand.
Step 2. Learn Your Framework—But Which Framework?
The sheer number of frameworks available is also quite daunting. To start out, I recommend using a framework with plenty of documentation and StackOverflow postings to help you get through the initial pain phase. Then, find a good Github that has a scaffold for the application using tools you can work with, to help you get it up and running quickly. Yeoman is a scaffolding tool for web applications which will setup the project for you, and if you use its generator, it can even create the relevant model, view, controller, and test files. While this does make it easier, I would advocate against using it unless you fully understand what it is doing.
While it doesn’t make sense to only be good at the framework, it is helpful to know the key features in the one you do decide to use. My most recent experience includes Angular and I would suggest focusing on a few concepts; the Angular website has pretty good explanations of these. The sample application we will work on in the second post will have working examples of these concepts.
- Angular Scope
- Angular Routing (with $route, with ui-router). ui-router allows for multiple nested views.
- Angular Directives
- Angular Services
- Angular Digest Cycle and $apply()
As with every language, it is good to focus on best practices for the framework that you are working with. Java best practices do not work for web, and vice versa. Following your frameworks best practices also helps with long term code health and maintenance.
Do not fall into the trap of using the most popular framework to solve every problem you encounter. I suggest a framework to start out with so that you can get a mini project up and going. It will be helpful later on to build a project without any frameworks so you have a better understanding of the foundations.
Step 3. Dependency Management and Build Systems—So Many Options!
For Android, nowadays you would typically use Gradle as your dependency management and build system. For web, you will most likely be using bower, or npm, or a combination of the two, to manage and install your packages. Gradle is a lot more powerful — it is a powerful dependency management tool, integrates with other build tools, and has an expressive build language and API.
Getting your web application ready for deployment involves a process of minification and obfuscation of your code. You can read about it in greater detail here. It essentially means that your code will be harder to copy and it will be optimized to be more lightweight to transmit across the network. This is equivalent to generating an apk to be installed. Your code is really only obfuscated and minified when it is supposed to be “production” ready, done through the build system you choose. Also, it can still be run in debug mode if you just launch your local server and you retain the ability to test on your browser.
There are a variety of options available to setup a local server to get your code running. The easiest option available to you is the python SimpleHTTPServer. This will get you going locally and you can focus on developing rather than on the build system.
When it is time to deploy you can use grunt or gulp, both popular build systems. There is only a few keywords you need to know to build the application, but the configuration files for them can get quite tricky. It would help to grab a working grunt or gulp file from a github or a scaffold. It is not as straightforward to use, but infinitely more powerful.
Step 4. Testing—Your Sanity Check
I have some experience with implementing TDD for Android using a combination of Robolectric and Mockito. It is a platform that hasn’t been around for as long as web though, and it is definitely evident. As such, I am pleased to assure you that testing on web is a lot easier. This is one of the points that web excels in – there has been a lot of effort put into creating great testing tools over the past few years. The tools I have used include:
- Jasmine – If you use PhantomJS you can use Jasmine for headless testing as well, which can be a nice bonus at times.
- Mock objects vary from framework to framework. Jasmine uses spies, Angular has its own testing framework for mocking objects (ng-mock).
There are essentially two things you will be testing: your mock API returns what you expect and binds this to the view in a certain way, and that your views are populated correctly based on the results of your API. How you go about doing this is up to you.
Almost every project should be easily configurable to run on a CI of your choice (Jenkins, Travis, Docker, etc.). Travis and Docker are the better choices as they do not tie you to a physical machine and it is easy to duplicate the environment.
Step 5. Styling—Make it Beautiful
In Android you have colors.xml, styles.xml, drawables, gradients, shapes, and a few more. All of these are organized into their own directories. For web, you have CSS. Plain, pure CSS can be difficult to work with and complicated—so use either SASS or Less. These are CSS preprocessor languages that include inheritance, allowing your styles to be much more modular.
A styles file should group together a bunch of design elements, and you can do that in Less/SASS with mixins. You can also override elements of a style and inherit from other styles when necessary. Less/SASS actually makes creating your styles a lot easier and more straightforward.
It is also important to know about CSS selectors so that you can easily do things like touch, hover, and selected states, as well as more interesting things like selecting all elements of a certain type, or sibling, or similar action.
As a general rule, people use bootstrap in their project, so they can make things look presentable relatively quickly. It allows for a fair bit of styling to be done, and has the added benefit of being responsive and mobile friendly. It lets you setup your layouts, customize HTML elements, and has a large glyphicon set that you can use. Another approach, which some developers prefer, is to use the gumbyframework, which combines bootstrap and SASS, so you just manage the one dependency.
Android vs Angular Lifecycles
There are many design patterns that developers use to structure their application. MVC (Model View Controller) is one pattern that is commonly used. MVC is a concept where you have a model that represents your data, a view which renders the model as a user interface, and a controller which handles user interaction and events. It is meant to split the three parts so you have lower coupling and higher cohesion throughout your application.
Android uses the MVC pattern, where the objects that you load/update asynchronously are your models, the XML files are your view, and the activity/fragment/adapters act as the controller.
Angular uses the MVVM (Model-View-ViewModel) design pattern. This pattern is trying to further separate the UI from the business layer and behaviour in an application. The model and view are the same as before, but the ViewModel is the current state of the model and exposes this information to the view directly through property and command bindings. The important takeaway is that Angular has two way data binding, and provides a nice separation of logic and UI.
In Android, there is no two-way data binding (unless you use a framework or library such as Liason). This means changes or updates to the model will update the view when you trigger a refresh manually. To update a value in the activity you attach an event listener to the views to update the value.
The Android lifecycle of an application revolves around a user starting, navigating, and backgrounding the application. An activity/fragment is created, paused, destroyed, etc. as the user enters a screen, pushes it to the background, or has it removed from the navigation stack.
In Angular, the $digest() cycle updates the views whenever it realizes that a component is dirty (usually triggered by a model/event change).
$digest() will go through the Angular controllers or directives and check the model components that are rendered to the view. It checks and evaluates its “watch” expressions, and compares values to see if a component is dirty and needs to be updated. If it is dirty, the digest() cycle will be kicked off. $apply() is used to trigger the $digest() call manually if you want it to update outside of the normal lifecycle.
A visualization of the overall Angular system:
Learning to make front end web applications requires learning a few things in parallel—the language, the framework of choice, the test framework, the build system, and the different ways you can style things. It also follows more of an MVVM pattern, rather than a tightly coupled MVC as in Android. However, as is always the case, if you have the concept or general idea of what you are trying to achieve, you can figure out how to get things done with relative ease.
The dynamic nature of the language and the sheer number of packages and components involved as opposed to the safe environment that Android Studio provides can make it frustrating at times. However, once you have learned the basics, the knowledge and skills can be easily transferred and applied over and over again. This post should give you an intro to web development with Angular. Once you have an understanding of the basics, then you can delve deeper and decide which (if any) framework to use, your own styles, and think about stack decisions more critically.
Thank you to Derek Webb and Rafay Khan for the editing :)
About the Author