Geeks With Blogs
Developers Friendly

Through this post I am trying to demonstrate how to write a custom service in AngularJS.

Why custom Service?

- Reusability
    Services are used to perform specific operation Or to write piece of code that doesn't fit in Directive or model. Say for example we have to call an API and capture data what we receive from API and perform some operation
    on that data.In such cases its a better practice that we take out such piece of code and keep it separately from any directive so that we can encapsulate code and which can be reused when ever required.

- Same data can be shared across application
    These services are singletons. Single instance for services will be used across the application.

- Reduce complexity
    As we encapsulate code the script files will be easier to understand and manage and enhance whenever required

By default AngularJS provides many inbuilt services to perform many specific operations such as $http, $resource, $q, $anchorScroll, $cacheFactory, $compile, $parse, $locale, $timeout, $exceptionHandler, $filter, $cookieStore, etc..

Instead of using $http from directive lets encapsulate it inside our custom service and lets expose custom service, by doing this user need not to worry what our custom service do under the hood.
To implement this, lets use publicly exposed API “https://api.github.com/users/angular” which gives list of users and lets try to bind this to Index.html page.

Service.js:

Our custom service name would be ‘github’

(function(){
    var github =  function($http){   //github name of custom service
        var getUser = function(userName){
            return $http.get("https://api.github.com/users/" + userName)
                        .then(function(response){
                                return response.data;
                            });
        };
        var getRepos = function(user){
            return $http.get(user.repos_url)
                        .then(function(response){
                            return response.data;
                        });
        };
        var getRepoDetails = function(username,repoName){
            return $http.get("https://api.github.com/repos/" + repoName)
                        .then(function(response){
                            return response.data;
                        });
        };
        return{
            getUser : getUser,
            getRepos: getRepos,
            getRepoDetails : getRepoDetails
        };
    };
    var module = angular.module("githubViewer"); // Loading app
    module.factory("github", github);  //Registering custom service to application
}());

UserController.Js: Controller used to bind data into view

(function() {

    var app = angular.module('githubViewer');

    app.controller('UserController',['$scope','github','$routeParams','$location',  //Consuming custom service ‘github’
                function($scope, github, $routeParams,$location) {

        var onUserComplete = function(data)
        {
            $scope.EnableRepos = true;
            $scope.IsError = false;
            $scope.User = data;
            var repo = $scope.getRepos();
        }
        var OnReposComplete = function(data){
            $scope.Repos = data;
        }
        var onError = function(error)
        {
            $scope.IsError = true;
            $scope.Error = "API didn't return response";
        }
        $scope.getRepos = function(){
            github.getRepos($scope.User)  // Invoking method from custom service
            .then(OnReposComplete, onError);
        }
        $scope.getRepoDetails = function(repo){
            $location.path("/RepoDetails/" + $scope.userName + "/" + repo.full_name);
        }
        $scope.userName = $routeParams.username;
        github.getUser($scope.userName).then(onUserComplete,onError);  // Invoking method from custom service
    }]);
}());

User.html: //Child page which will be included in Index.html

<div>
    <div ng-show="User">
        <div>
            <div>{{User.name}}</div>
            <div ng-show="{{IsError}}">{{Error}}</div>
            <img ng-src="{{User.avatar_url}}" alt="{{User.name}}" height="100px" width="100px"/>
        </div>
        <p>
        <span>Order By:</span>
        <select ng-model="RepoSortOption">
            <option value="name" ng-selected="true">Name</option>
            <option value="stargazers_count">Stars</option>
            <option value="language">Language</option>
        </select>
        <span>Direction:</span>
        <select ng-model="RepoSortDirection">
            <option value="+" ng-selected="true">Ascending</option>
            <option value="-">Descending</option>
        </select>
        </p>

        <table border="1" id="reposDetails">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Stars</th>
                    <th>Language</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="repo in Repos | orderBy:RepoSortDirection + RepoSortOption">
                    <td><a href="#RepoDetails/User.login/repo.name">{{repo.name}}</a></td>
                    <td>{{repo.stargazers_count | number}}</td>
                    <td>{{repo.language}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <a href="#/UserSearch">Back to search</a>
</div>

Index.html: User.html will be included in Index.html

<html ng-app="githubViewer">
    <head>
        <!-- SCROLLS -->
        <!-- load bootstrap and fontawesome via CDN -->
        <!-- <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" /> -->

        <!-- SPELLS -->
        <!-- load angular and angular route via CDN -->
        <!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script> -->
        <!-- <script src="../../Scripts/lib/angular.min.js"></script> -->
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
        <script src="../../Scripts/Hands-on/app.js"></script>
        <script src="../../Scripts/Hands-on/Application.js"></script>
        <script src="../../Scripts/Hands-on/UserSearchController.js"></script>
        <script src="../../Scripts/Hands-on/UserController.js"></script>
        <script src="../../Scripts/Hands-on/RepoDetailsController.js"></script>
        <script src="../../Scripts/Hands-on/Services.js"></script>
        <script src="../../Scripts/Hands-on/Script.js"></script>
        <title>Index</title>
    </head>
    <body>
        <div ng-include="'Header.html'"></div>
         <!-- MAIN CONTENT AND INJECTED VIEWS -->
        <div id="main">
            <!-- angular templating -->
            <!-- this is where content will be injected -->
            <div ng-hide="true">{{message}}</div>
            <div ng-view></div>      // Where all child pages will be included
        </div>
    </body>
</html>

Note: Complete source code is available @ https://onedrive.live.com/redir?resid=5A70375467BBACD0%21116 for reference. 

Hope this helps.

Thanks!

Posted on Tuesday, November 25, 2014 4:51 AM AngularJS | Back to top


Comments on this post: Custom Services in AngularJS

# re: Custom Services in AngularJS
Requesting Gravatar...
Hi,

I am developing application using angularjs. I need to know, Can I make Ajax call to SAP RFC and consume and bind data in front end..

As we mention "POST" and "GET" in Ajax..Can you make call same way for SAP RFC..is it compatible.
SAP RFC are placed at different server.

Pls help

Left by Kaushik on Jun 26, 2015 10:58 AM

Your comment:
 (will show your gravatar)


Copyright © Manjunath K | Powered by: GeeksWithBlogs.net