Blogger news

Blogger templates

Sunday, July 20, 2014

Services in AngularJS

If you are new to AngularJS I would prefer to go through my introduction blog on AngularJS before read this article

AngularJS services are singleton objects and it holds some business logic. Separation of concern and dependency injection are the main goals of services in AngularJS. Angular services are substitutable objects that are wired together using dependency injection.
 As a best practise Your controller must be responsible for only binding model data to views using $scope. It does not contain logic to fetch the data or manipulating it. For that we must create singleton objects called services. Wherever we want to use the service, we just have to specify its name and AngularJS automatically  inject these objects. Functions in services can be called from anywhere; Controllers, Directive, Filters etc.
Putting business and other logic within services has many advantages. First it fulfils the principle of separation of concern or segregation of duties. Each component is responsible for its own work making application more manageable (I strongly suggest to read SOLID principles if you are not familiar with. As a software developer you MUST  know what are SOLID principles ). Second this way each component can be more testable. Enough theory, lets switch to an example. First I will create an example without service( just a controller) and I will explain why we need a service. 
My example is to get details of team which include team name and team members count. So my view looks like below
  <!DOCTYPE html>
  <html ng-app="TeamModule">
  <head lang="en">
      <meta charset="UTF-8">
  <body ng-controller="TeamController" ng-init="GetTeamDetails()">
      TeamName:- {{TeamDetails.Name}}
      TeamSize:- {{TeamDetails.TeamSize}}
      <script src="../Scripts/AngularScripts/angular.min.js"></script>
      <script src="../Modules/AssociateModule.js"></script>
      <script src="../Controllers/AssociateController.js"></script>

As you know now we have to create module and controller
var TeamModule = angular.module('TeamModule', []);

TeamModule.controller('TeamController', function ($scope) {

    $scope.GetTeamDetails = function () {
        $scope.TeamDetails = { Name: "ThunderCats", TeamSize: 10 }        //Assume this information we are retrieving from database  

As you can see in our controller we have created a function 'GetTeamDetails' which returns a JSON object with properties Name and TeamSize. Returned JSON object we assigned a property 'TeamDetails' and in view we bind each of the property to two divs. when you view this in browser output will be as below,

Nothing wrong here and everything works fine. Then why you need a service?? 
Well assume that your application is not small like this (In example we just hard-coded JSON object but in real time it may return from database)  and you need many complex business logic to do and you need to call REST services to connect to database to get details. If you suggest one place, controller to write all those logic then I would say you are not a good developer. Yes developer should always think about separation of concern while writing each line of code and always mind SOLID principles while writing code.

This is where services or factory comes to picture. It's all about separation of concern and loosely coupling. So time to register our first service and which is below. 
TeamModule.factory('TeamFactory', function () {

    var GetTeamDetails = function () {
        return { Name: "ThunderCats", TeamSize: 10 };

//This approach of returning methods/properties is called “Revealing Module Pattern” in JavaScript
    return {
        GetTeamDetails: GetTeamDetails

So we created our first service. quiet easy right? As you can see we called 'factory' method of our module. First parameter of factory function is the service team and here it is 'TeamFactory'.  Second parameter is a callback which returns JSON object of team details.

Careful when you naming the service. Avoid giving name which starts with '$' as AngularJS in built services has  naming convention which begins with '$' so if you follow same convention it may collide with built in services.

Next we have to inject the service we created to our controller. Let's see how it is,
TeamModule.controller('TeamController', function ($scope, TeamFactory) {

    $scope.GetTeamDetails = function () {
        $scope.TeamDetails = TeamFactory.GetTeamDetails();

See how we inject 'TeamFactory' service here, very simple. Now 'TeamFactory' is an object so we can call 'TeamFactory.GetTeamDetails()' from our controller. It means we have given responsibility of getting team details to the service we created. Think how easy it is to maintain now also we achieved separation of concern and SRP (Single responsibility principle).  

Don't forgot to add JavaScript reference of service in your view.
Angular services are,
Lazily instantiated – Angular only instantiates a service when an application component depends on it.Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.

Inbuilt AngularJS services

Before I explain built in AngularJS service please go through my blog on Routing in AngularJS . In that I am using one of the built in services, $routeProvider.
As you can see there we are injecting $routeprovider service to the call back function of config function and we injected 'ngModule' which is the dependent module for $routeprovider. $routeprovider service is for routing logic. 
You can see more built in service in AngularJS official site 
So one more feather in your cap, services in AngularJS.

1 comment:

Sanju John said...

Thank you so much is really helpful and your way of writing is very simple and clear.Really appreciate your effort and it helps us to start our new development for hybrid mobile application. waiting for more useful blogs from you including node.js

Post a Comment