Angular Tutorial – Part 5: Understanding and implementing Services

In this article we will discuss about the services in angular. We will see how and why services are useful. We will try to use some built in services and create our own service in angular.


Link to complete series

  1. Angular Tutorial – Part 1: Introduction to Angular.js
  2. Angular Tutorial – Part 2: Understanding Modules and Controllers
  3. Angular Tutorial – Part 3: Understanding and using Directives
  4. Angular Tutorial – Part 4: Understanding and implementing Filters
  5. Angular Tutorial – Part 5: Understanding and implementing Services
  6. Angular Tutorial – Part 6: Building and Validating Data Entry Forms
  7. Angular Tutorial – Part 7: Understanding Single page applications and Angular routing

Background

In our web application we will always have some business logic and server communication to fetch/save the data to the server. What is the best place to do such kind of things. We could write this code in controller and have a working application but should we write this code in the controller is the question.

There are two major problems if we put our business logic and server communication in the controllers. First problem is that this piece of functionality will not be reusable i.e. If we want to reuse some behaviour in other controllers, we will have to rewrite this code. The second problem is from the best practices perspective. If we put all this code in the controllers then effectively we are violating the single responsibility principle as our controller should only be responsible for populating the $scope properties that are needed by the associated view. Also, there is no separation of concern if we put all the business logic on controller, we will end up having spaghetti code again in our controllers.

So how can we write our code in such a manner that we have a good separation of concern i.e. every business logic component is separate from each other and from the controller. Also, how can we use and reuse business logic components from the other parts of the application. The answer to this question is angular services.

Angular let us create reusable stateless components that can be used from other parts of the application. These are called services in angular. A service is a singleton object that can be defined to contain any piece of business logic. They can then be used from other part of the application like controllers, directives, filters and perhaps other services.

So to look at the concept of the services more closely and understand the topic in a much better manner, let us introduce a service in our application. So far we have created an application that shows a list of books on click of a button.

Angular5_1

The controller for this app looks as following.

What we are doing in the above controller is that we are populating the list of books with some hard coded values. But ideally they should come from server. Lets say we want to introduce angular service in this application. In fact we will create two services for this application. One to get this hard coded list of sample books. Second service will fetch the similar list of books from server using a RESTful API. So lets get started.

Using the code

Before we start creating the service for our applicatio, let us understand a few basic things.

How to create a Service

The first thing to remember is that there are four ways to create a service in angular. Using any of these ways will give us a stateless singleton object that can be used across the application. Which method should be used largely depends on the pattern that we want to follow, what exactly this service is meant for and how we would want to use this service. We will not be discussing or comparing these approaches as that would be digressing for this article(perhaps later article could cover this). In this article, we will be using the factorymethod to create our service which is the angular implementation of factory pattern to create the service object.

What we need to do to create our service class is to use the factory method on the angular module and associate the service function with it. Lets create the skeleton for localBooksServicewhich will return a hard coded list of books to our controller.

Now before we could go and write the internal implementation of this service, perhaps we should look at a javascript pattern that is used for implementation. It called the Revealing Module Pattern.

Understanding Revealing Module Pattern

From the best practices perspective(also the oops fundamentals), we should always encapsulate the internal implementation into a class and let the user see only the public abstraction. But since we are talking JavaScript here, there is no way we can put access specifier type of things in our service implementation. So how can this be achieved. This can be achieved by using a JavaScript pattern called revealing module pattern.

In this pattern what we do is that we let the function return an object. so the caller of this function will get the instance of this object. So lets say we will return an object that will contain the list of books.

Right now this is just an empty array that we are returning. How can we have the actual list of books associated. Since inside this function, we can access the internal variables and functions, why not have this list of books as a function level variable and then return it to the user.

On the same lines, we can also have a function defined inside which can be revealed outside using this return object.

Implementing our Service

Now with this revealing module pattern we have achieved some level of encapsulation as the function will only be exposing the object that is being returned and can remain shielded from actual implementation. let us now move the list of these hard coded books in our localBooksServiceand look at the implementation of our service.

Using the Service

Now that we have the service ready, lets see how we can use it from our controller. The first thing that we need to do is to pass the dependency of this service on our controller in a minification safe manner (this we saw in previous article). and then we need to use the service to get the list of books instead of hard coded books. Let see how our controller looks after these changes.

Using Angular Built In Service

Angular also comes with a lot of built in services that we can use. A few of them are $location, $window, $resource and $http. We can look at angular documentation to see what a specific service provides and how can we use them in our application. For this example, let us use the $http service. What we will do is that we will implement another service called remoteBooksServiceand will use this $http service inside that to fetch the books from the server.

Note: What I have done is that I have created an ASP.NET Web API project that can be used to perform the CRUD operations on a book database located on the server. Please find the API project attached to see the Web API details. Alternatively, we can create a simple REST based service using node or any other technology and in our angular application, we just need to refer to the URL where that service is hosted.

Lets see how we can use the $http service in our own service. The first thing we need to do is to inject this service in our service. Once this is injected, we can use the get method of $http to retrieve the result from the server. My server API is running at: http://localhost:57386/api/Books

Now lets inject this service in our controller and add one more function in our controller that will use this service to get the remote list of books. $http.getreturns a promise and since we are directly returning that promise from our service, our controller needs to handle that promise and populate the list of books.

Now if we run the application and click on the fetch from remote, we will get the books list from the server.

Angular5_2

Note: The above shown approach to use the $http service is rather crude as our main focus was on looking at how we can use the service and create our own service that is using other services. The ideal solution for using $http would involve using the $Q defer API which I strongly recommend reading about. We will not be talking about it here as its not in the scope of this article.

Point of interest

In this article we looked at the concept behind services in angular. We looked at how we can implement our own service and how we can reuse the built in angular service by looking at an example usage of $http service. This has been written from a beginner’s perspective. I hope this has been informative.

Download the sample code here: SampleApp5  BooksAPI