Services in AngularJS simplified with examples

Read: 21 points cheat sheet on AngularJS controller and the $scope object

What is service?

  • It provides us method to keep data across the lifetime of the angular app
  • It provides us method to communicate data across the controllers in a consistent way
  • This is a singleton object and it gets instantiated only once per application
  • It is used to organize and share data and functions across the application

Two main execution characteristics of angular services are that they are singleton and lazy instantiated. Angular only creates instance of a service when an application component depends on it. On the other hand each application component dependent on the service work with the single instance of the service created by the angular.

image

Keep in mind that services are singleton object and gets instantiated once per angular app using the $injector and they gets created when angular app components need them.

Let us start with creating a very simple service. This service will find square of a given number. It is a good idea to put all the service in a separate JavaScript file. We have created service.js file and inside that creating a service or registering a service using the service method as shown below,

var CalculatorService = angular.module('CalculatorService', [])
.service('Calculator', function () {
    this.square = function (a) { return a*a};

});

An AngularJS service can be created or registered or created in four different ways,

  1. Using the service() method
  2. Using the factory() method
  3. Using the provider() method
  4. Using the value() method
  5. Using the constant() method

Further in the post we will talk about other options to create the service. Above we have created the calculator service using the service() method.

To use the service in the controller, we are passing the service module CalculatorService as dependency in the application module. Next in the controller we are passing name of the service Calculator to be used.

var myApp = angular.module('myApp', ['CalculatorService']);
myApp.controller('CalculatorController', function ($scope, Calculator) {

    $scope.findSquare = function () {
        $scope.answer = Calculator.square($scope.number);
    }
});

On the view we are using the controller to do the data binding as shown below,

<div class="container">
        <div>
            <div ng-controller="CalculatorController">
                Enter a number:
                <input type="number" ng-model="number">
                <button class="btn btn-danger" ng-click="findSquare()">Square</button>
                <div>{{answer}}</div>
            </div>
        </div>
    </div>

An angular application will render as shown below,

image

We can create a service using the factory as shown below. We are creating the service to reverse the string.

CalculatorService.factory('StringManipulation', function () {

   var r=  function reverse(s) {
        var o = '';
        for (var i = s.length - 1; i >= 0; i--)
            o += s[i];
        return o;
    }

   return{
       reverseString: function reverseString(name)
       {
           return r(name);
       }
   }

});

In the controller the StringManipulationService can be used as shown below:


myApp.controller('CalculatorController', function ($scope, Calculator) {

    $scope.findSquare = function () {
        $scope.answer = Calculator.square($scope.number);
    }
});

On the view we are using the controller to do the data binding as shown below,

<div ng-controller="StringController">
                Enter Name:
                <input ng-model="name">
                <button class="btn btn-info" ng-click="findReverse()">Reverse Name</button>
                <div>{{reversename}}</div>
            </div>

An angular application will render as shown below,

image

Let us understand difference between creating a service using the service() method and the factory() method.

  1. Using the service() method uses the function constructor and it returns the object or instance of the function to work with
  2. Using the factory() method uses the returned value of the function. It returns the value of the function returned after the execution

If we want to register a service using the function constructor, in that scenario we will use service() method to register the service. If we use factory() method to register the service it returns the value after execution of the service function. It can return any value like primitive value, function or object. So service() method returns the function object whereas factory() method can return any kind of value.

In further post we will talk about other ways of creating service. Now let us work on a full working example of using service in an angular app. We are going to create an application which will perform the followings,

  1. List students from the database
  2. Add a student to the database

Roughly architecture of the application can be drawn as shown below,

image

This post will not cover how to create a JSON based WCF REST Service. With the assumption that REST based service is already in place to retrieve the students and add a student, we will write the angular application.

The Service

var StudentService = angular.module('StudentService', [])
StudentService.factory('StudentDataOp', ['$http', function ($http) {

    var urlBase = 'http://localhost:2307/Service1.svc';
    var StudentDataOp = {};

    StudentDataOp.getStudents = function () {
        return $http.get(urlBase+'/GetStudents');
    };

    StudentDataOp.addStudent = function (stud) {
        return $http.post(urlBase + '/AddStudent', stud);
    };
    return StudentDataOp;

}]);

We are creating the service using the factory(). There are two methods in the service. getStudents fetch all the students using the $http.get whereas addStudent add a student using the $http.post. In the service we are using other inbuilt angular service $http to make the call to the service. To use the $http service, we have to pass this as dependency to the service factory() method.

Once service is created, let us create the controller which will use the service to perform the operations.

The Controller 

var myApp = angular.module('myApp', ['StudentService']);

myApp.controller('StudentController', function ($scope, StudentDataOp) {
    $scope.status;
    $scope.students;
    getStudents();

    function getStudents() {
        StudentDataOp.getStudents()
            .success(function (studs) {
                $scope.students = studs;
            })
            .error(function (error) {
                $scope.status = 'Unable to load customer data: ' + error.message;
            });
    }

    $scope.addStudent = function () {

        var stud = {
            ID: 145,
            FirstName: $scope.fname,
            LastName: $scope.lname
        };
        StudentDataOp.addStudent(stud)
            .success(function () {
                $scope.status = 'Inserted Student! Refreshing Student list.';
                $scope.students.push(stud);
            }).
            error(function (error) {
                $scope.status = 'Unable to insert Student: ' + error.message;
            });
    };
});

In the controller we are adding getStudents and addStudents functions to scope. As it is clear from the name that these functions are used to fetch students and add student respectively. As a dependency StudentSevice module is passed in the module and in the controller we are passing the StudentDataOp service as the dependency.

Other important thing to notice is that, we are creating student object to be added using the $scope object properties like fname and lname. These properties are set to the $scope on the view.

The View

View is very simple. StudentController is attached to the view. There are two section in the view. In first section we are taking user input to create the student. In the second section, in a table all the students are listed.

<div ng-controller="StudentController">
            <form class="well">
                <input type="text" name="fname" ng-model="fname" placeholder="first name" /> <br/>
                <input type="text" name="lname" ng-model="lname" placeholder="last name" />
                <br /><br/>
                <input type="button" value="add student" ng-click="addStudent()" class="btn btn-primary" />
            </form>
            <br/>
            <table class="table">
                <tr ng-repeat="s in students">
                    <td>{{ s.FirstName }}</td>
                    <td>{{ s.LastName }}</td>
                    <td>
                        <a href="#" class="btn btn-info" ng-click="edit(contact.id)">edit</a>
                        <a href="#" class="btn btn-danger" ng-click="delete(contact.id)">delete</a>
                    </td>
                </tr>
            </table>
        </div>

In the input form we are setting fname and lname properties on the $scope object and then calling addStudent() function of the controller to add a student to the database.

In the table using the ng-repeat directive all the students are listed. We have put two buttons for edit and delete. These buttons are not performing any task as of yet. In further posts we will add edit, delete and search functionality.

If you are following along the posts, may be you want to these functionality of your own and share experience with me.

On running the application, you will get form to add a student and all students listed in the table.

clip_image002

This is how you can create and use angularJS service in application. I hope you find this post useful. Thanks for reading. Happy coding.

Teaching AngularJS class in Noida on 21st February: Join for free

 

Register to join the class for free

image

With the help of C# Corner Delhi Chapter , I am teaching AngularJS on 21st February.

Any aspired developer, engineer or student can attend the class for free. All you need to do is to become member of C# Corner Delhi Chapter and Register for the class here .

It will be a three hour class and I will cover the following topics,

Introduction to JS functions and AngularJS: Hour 1

  • A leap in JavaScript function
  • Understanding JavaScript Objects
  • Prototype in JavaScript
  • Getting started with AngularJS
  • Bootstrapping AngularJS
  • Writing first Hello World app in AngularJS
  • Setting up Visual Studio for AngularJS
  • Setting up Sublime, Node and Bower for AngularJS Development
  • Understanding basic directives, binding and expression
  • Basic testing of Angular App

Controller, $Scope and Directive: Hour 2

  • What is $Scope
  • What is $RootScope
  • What is $Scope Hierarchy
  • What is Controller
  • What is Module
  • Controller in Module
  • Controller Hierarchy
  • $http service in Controller
  • Understanding different directives
  • Built in Directives and Event Directives

Service, Routing: Hour 3

  • Understanding Service
  • Using Service
  • Using Service in Controller
  • Different Service type
  • Understanding Routing
  • Adding your first route
  • Routing and browser history
  • Creating Default Route

Excited? So see you on 21st at 9.30 am in C# Corner Noida office. Class will happen at the below location

H-217, First Floor, Sector 63, Noida

Register here to join the class and yes do not forget to say a Thanks to amazing @csharpcorner team on social media.

How to use NodeJS, Express, and Bower to Create AngularJS apps

Read full article on the Infragistics blog

Recently I heard – “IDE makes you ignorant, so do not over rely on the IDE”. Being a .NET developer, we cannot think our lives beyond Visual Studio and hence somewhere we become ignorant. We really don’t care about the behind the scene complexities. We create a project by selecting a specific project template and mange different required packages using the NuGet package manager. Super simple? Isn’t it?

This article may help a .NET developer to use JavaScript at the server and at the client to create an application. NodeJS will run at the server and Angular to create application for the client.

image

Note: Image taken from the web. A special thanks to original image creator.

We will start with creating an angular application in the Visual Studio and then proceed to create the same angular application using few components of the MEAN stack. We will use NodeJS, Express, Bower to create the angular application.

We will cover the following topics,

  • AngularJS application in Visual Studio
  • Installing the NodeJS on Windows
  • Setting up the sublime text for JavaScript development
  • Installing Bower
  • Installing angular dependencies using the bower
  • Creating angular application
  • Installing Express
  • Creating web server using the express to serve the angular app

Read full article on the Infragistics blog

21 points cheat sheet on AngularJS controller and the $scope object

This blog post is a 21 points cheat sheet on the AngularJS controller and the $scope object. These points can be used a quick notes while working with two important components of Angular app controller and the $scope object Notes on $scope object $scope is a glue between the view and the controller. It connects controller with the view. image

  1. $scope serve as the glue between controller and the view
  2. The $scope is the connection between the HTML and the view
  3. View and the model both have access of $scope
  4. In context of MVC , $scope can be seen as ViewModel
  5. $scope provides execution context for the DOM and the expression
  6. $scope provides an execution context in which DOM element is bound
  7. $scope are the source of the truth
  8. $scope gets modified when View changes and the view gets modified when $scope changes its value
  9. The $scope object is plain JavaScript object. We can add and remove property as required
  10. $scope holds data and functions from controller that should be displayed and get executed in view
  11. The $rootScope is eventual parent of all the $scope
  12. $rootScope is top most scope in on DOM element with ng-app directive
  13. In angular all the $scope are created with prototypal inheritance
  14. $scope has access to their parent scope
  15. $scope contains data and the functionality to be used to render the view
  16. For each controller creation and new $scope gets created
  17. It is ideal to contain the application logic in the controller and the data in the $scope of the controller.
  18. When $scope object is not needed in the view, scope will be cleaned up and destroyed
  19. Directives does not have their own scope but with some exceptions ng-controller and ng-repeat
  20. When angular starts running all the $scope are attached to the view
  21. $scope pass data and behavior to the view

Example: Adding property to $rootScope To add a property to $rootScope directly, pass $rootScope as parameter to the controller as shown below. However it is not advisable to add properties to $rootScope directly.

var myApp = angular.module('myApp', []);
myApp.controller('RootController', ['$rootScope', function ($rootScope) {

    $rootScope.name = &amp;quot;dj&amp;quot;;

}]);

On the DOM added property of $rootScope can be rendered in the expression as shown below,

<div ng-controller="RootController">
<h1><strong>{{</strong>name<strong>}}</strong></h1>

</div>

Other way you can add property to the $rootScope object directly using the run method on the application module.

angular.module('myApp', [])
      .run(function ($rootScope) {
          $rootScope.name = &amp;quot;World&amp;quot;;
      });

To use this you don’t need controller to attach with the View and can be used in the application as shown below,

   <div ng-app="myApp">
        Hello {{name}}
    </div>


Notes on the controller

Controller adds behaviour and data to the $scope object. It gets created on the view using this ng-controller directive. Each controller has its own $scope object. image

  1. It’s a JavaScript constructor function that is used to augment the $scope object
  2. Controller takes $scope as parameter and attach data and behavior to this
  3. Controller is attached to DOM using the ng-controller directive
  4. Each controller has its own child $scope
  5. Controller set up the initial state of the $scope object
  6. Controller adds behavior to the $scope object
  7. Do not use Controller to manipulate DOM : It should only contain the business Login not the DOM manipulation
  8. Do not use controller to format the input
  9. Do not use controller to filter the output
  10. Do not use controller to share the code across the controller
  11. Never create the service instance inside the controller
  12. A Controller should mainly contain a simple business logic
  13. It should not try to do many things
  14. All the common functionality should go the service and the later service can be injected to the controller via dependencies
  15. Controller name starts with the capital letter and ends with the Controller
  16. Whenever new controller gets created on the page, angular pass a $scope object to it.
  17. Custom actions to be called from the view can be created as behavior of function in the controller augmenting to the $scope object
  18. Controller can be attached to different level of DOM hierarchy, hence its create hierarchy of the $scope.
  19. $scope in child controller can access and override data and behavior attached to $scope of the parent controller.
  20. Other directives or services to be used in the controller must be passed as parameter in the controller function constructor
  21. Controller should provide data and business logic to a particular View

Example: Creating a simple controller Let us create a simple controller with two functions as behavior and one data. Functions are either adding or subtracting 1 from the counter attached as property to $scope object.

var myApp = angular.module('myApp', []);
myApp.controller('mycontroller', ['$scope', function ($scope) {

    $scope.counter =0;
    $scope.add = function () { $scope.counter += 1;}
    $scope.sub = function () { $scope.counter -= 1; }
}]);

On the DOM controller can be used as shown below,


  <div ng-controller="mycontroller">
            <h1>{{counter}}</h1>
            <button class="btn btn-info" ng-click="add()">+</button>
            <button class="btn btn-danger" ng-click="sub()">-</button>
        </div>


When you use controller to another DOM element, a new instance of controller will get created.


<div class="container">

        <div ng-controller="ParentController">
            <h2>{{age}}</h2>
            <div ng-controller="ChildController">
                <h1>{{name}}</h1>
                <h2>{{age}}</h2>
                <h3>{{grade}}</h3>
            </div>
        </div>


On running the application you will find that both the div has different values for the $scope data. Example: $scope inheritance Let us create a module with two controller ParentControler and ChildController. As you see ChildController is overriding age property on the $scope object.

var myApp = angular.module('myApp', []);

myApp.controller('ParentController', ['$scope', function ($scope) {

    $scope.name = "dj";
    $scope.age = 32;

}]);
myApp.controller('ChildController', ['$scope', function ($scope) {

    $scope.age = 22;
    $scope.grade = &amp;quot;A+&amp;quot;;

}]);

In the view we have created ChildController inside the ParentController div. In the ChildController $scope, there is no property called name. So angular will traverse to the ParentController to find the value of the name property. Also you can notice that age property is overridden in the ChildController, so the div attached with the ChildController will render overridden value of the age property.


<div class="container">

        <div ng-controller="ParentController">
            <h2>{{age}}</h2>
            <div ng-controller="ChildController">
                <h1>{{name}}</h1>
                <h2>{{age}}</h2>
                <h3>{{grade}}</h3>
            </div>
        </div>


I hope, these 21 points about the $scope object and the controller should help you in working with AngularJS. Thanks for reading.

What is Closure in JavaScript

JavaScript works on lexical scoping. To understand it in better way, let us consider the following listing,

function myapp() {
    var name = "foo";
    function greet() {
        console.log("hello " + name);
    }

    greet();
}
myapp();

As you see greet is the inner function of the myapp function, and it has access to the local variable of the outer function. When you run the above listed code “hello foo” will be printed in the console. This is because of the lexical scoping in the JavaScript. In the JavaScript an inner function has access to the variable from the outer function or the function it is nested in. In the JavaScript a scope of a variable is either global or to the function it is defined in. Each variables are hoist at the top of the scope.

Read Hoisting in JavaScript: Simplified here

Let us consider another code listing, slightly modified version of the snipped we discussed above. In this we are returning the greet function from the myapp function. Keep in mind that greet is the inner function whereas myapp is the outer function.

function myapp() {
    var name = "foo";
    function greet() {
        console.log("hello " + name);
    }

    return greet;
}

var result = myapp();
result();

To be surprised the above snippet will also give us the same output, and hello foo will be printed in the console.

Let us examine why it is happening? First observation should come to your mind that, once myapp() got executed, the local variable inside myapp function should not be available to use. Hence the expected output should be hello undefined. However we can still use the local variable in the function which is return from the function in which the local variable is defined. This is known as the CLOSURE. In above code snippet result is a JavaScript closure.

In JavaScript closure consist of the function and the environment in which the function was created. Keep in mind that JavaScript closure is an object and it contains the function and the environment at the time function was created.

 

image

In above code snippet result is a closure which has the information of the function and its environment when it was created. In this scenario environment is the local variable. So result is a closure which has the information about the greet function and the variable name. Let us consider one more example to understand closure


function app(name) {

    function greet(message) {
        return message + " " + name;
    }

    return greet;
}

var a = app("dj");
var result1 = a("hello");
console.log(result1);

var b = app("mahesh");
var result2 = b("whats'up");
console.log(result2);

In above code snippet a and b are the JavaScript closures. Since they are closure so they have information about function greet and the environment variables name and message. As output you will get hello dj and whatsúp mahesh. I hope this basic explanation of closure helps you.