In a sea of client side MVC web frameworks, Angular is becoming the most prominent one due to its increasing popularity. Unlike other MVC frameworks (Backbone, Ember), Angular uses HTML as the templating language and also allow us to build our own HTML directives that can be interpreted by the browser. One of the unique Angular's features are the dependency injection mechanisms which promote code reuse and make it easier to assemble the web application.
In this post we will focus on how to build a simple web application to highlight the most important building blocks every modern Angular application should have. So, let's start.
What we are going to build?
I bet you had already read a lot of tutorials where a todo like application was used to illustrate the basic concepts. I wanted to go step further and build a real time collaborative web application to manage the todo lists. The full source code is hosted on the github. Even simple, the application uses rather complete technology stack.
- MongoDB, document oriented NoSQL data store.
- Spring, the Spring MVC framework for building the RESTful web services. Spring Data had been used to simplify data access and persistence through Mongo repositories.
- SockJS, websockets to make the realtime application.
- Bourbon/Refills, is the SaSS based framework with very cool components and responsive grids.
- Bower for dependency management of web artifacts.
Going persistent with Mongo
Spring Data makes it extremely easy to access and manipulate the new generation data access technologies as well as relational databases, providing the well known Spring programming model such as POJOs, templates, etc. For instance, our
Todo entity could be modeled as follows.
@Document annotation identifies the domain object to be saved in Mongo. Spring Data provides the
MongoTemplate abstraction we could use to query and manipulate the data store. However, a more consistent and idiomatic approach can be achieved with the data repositories.
That's the whole code needed to enable the basic CRUD operations on Todo documents. Magic! Isn't it? It is also necessary to activate the repository scanning in the Spring XML configuration file.
Serving up the data via REST
The next step is to expose the HTTP endpoints the will be called from Angular to get todo lists, create new ones, change tasks priority or mark them as done. That won't be a big deal. Spring MVC controllers allow us the create lightweight REST services and map the methods with requests using the
@RequestMapping annotation. Let's see some code.
That's pretty straightforward. We have annotated the
TodoController class with
@RequestMapping annotations, so the Spring knows this class will act as the controller. Note how the controller receives the reference of the repository and how the
findAll method is called to get all created todos in Mongo. When the client (browser) requests the
api/v1/todos endpoint the
todos method will be triggered to respond with the JSON array of todo lists in the response body.
Pushing with web sockets
Every time a user adds a new todo list, delete the task or performs any other action, we want that changes to propagate to the rest of the users. Instead of pulling for the changes using the traditional XHR calls, the websockets open a bidirectional full duplex channel with the server. Once the connection had been established they can interchange data in real time.
Spring Websocket provides a SockJS endpoint which can be enabled with the following XML configuration.
This will boot up a broker on
/io endpoint so the clients can connect over the Stomp protocol. Here we also tell the Spring to use SockJS websocket emulation. If web browser doesn't support web sockets, SockJS will choose another transport.
On the client side, the Angular service is responsible for establishing the connection with websocket server upon application bootstrap.
subscribe function registers a callback that is called every time the content is being pushed from the server. For sending the messages to a subscribed topic, Spring provides the
SimpMessagingTemplate template. See the code below. Upon the creation of a todo list
convertAndSend will serialize a
Todo object to JSON and send it to the browser.
On the Angular side, we inject the
TodoService into the controller, and then call the
connect method to initiate the connection and register the callbacks that are triggered when message is received from the server.
Consuming the REST API
Angular ships with the built in
$http service that can be used to perform requests. For example to create a new todo list, we can call the
Similarly, we can send a GET request like this.
This function returns a special promise object which encapsulates the asynchronous action. In the controller we wait for the operation to complete, and then we provide the scope with the result.
Rendering the views
As we already stated, Angular uses the HTML templates to build up the views with the set of well known directives. They provide bidirectional data binding, iterations, conditional rendering, event handlers, etc. Here is a part of the view which renders todo lists.