AngularJS services
AngularJS services are substitutable objects that can be injected into directives and controllers via Dependency Injection. These objects consist of simple pieces of business logic that can be used across the app.
AngularJS services are lazily initialized only when a component depends on them. Also, all services are singletons, that is, they get initialized once per app. This makes services perfect for sharing data between controllers and keeping them in memory if needed.
The $interval
is another service that is available in AngularJS. The $interval
is the same as setTimeInterval()
. It wraps setTimeInterval()
and returns a promise when you register this service. This promise then can be used to destroy $interval
later on.
Another simple service is $log
. This service logs messages to the browser console. A quick example of this would be as follows:
myApp.controller('logCtrl', ['$log', function($log) { $log.log('Log Ctrl Initialized'); }]);
So, you can see the power of services and understand how simple pieces of business logic can be made reusable across the app.
You can write your own custom services that can be reused across the app. Let's say that you are building a calculator. Here, methods such as add
, subtract
, multiply
, divide
, square
, and so on, can be part of the service.
Coming back to our Search App, we used a factory that is responsible for server-side communications. Now, we will add our own service.
Note
Service and factory components can be used interchangeably. Refer to http://stackoverflow.com/questions/15666048/service-vs-provider-vs-factory for more information.
For instance, when the user searches for a given keyword(s) and posts displaying the results, we would like to save the results in the local storage. This will ensure that, next time, if the user searches with the same keyword(s), we will display the same results rather than making another AJAX call (like in offline mode).
So, this is how we will design our service. Our service will have the following three methods:
isLocalStorageAvailable()
: This method checks whether the current browser supports any storage APIsaveSearchResult(keyword, searchResult)
: This method saves a keyword and search result in the local storageisResultPresent(keyword)
: This method retrieves the search result for a given keyword
Our service will look as follows:
searchApp.service('LocalStorageAPI', [function() { this.isLocalStorageAvailable = function() { return (typeof(localStorage) !== "undefined"); }; this.saveSearchResult = function(keyword, searchResult) { return localStorage.setItem(keyword, JSON.stringify(searchResult)); }; this.isResultPresent = function(keyword) { return JSON.parse(localStorage.getItem(keyword)); }; }]);
Note
Local storage cannot store an object. Hence, we are stringifying the object before saving and parsing the object after retrieving it.
Now, our directive will use this service while processing the search. The updated mySearch
directive will look like this:
searchApp.directive('mySearch', ['ResultsFactory', 'LocalStorageAPI', function(ResultsFactory, LocalStorageAPI) { return { templateUrl: './directive.html', restrict: 'E', link: function postLink(scope, iElement, iAttrs) { var lsAvailable = LocalStorageAPI.isLocalStorageAvailable(); scope.search = function() { if (lsAvailable) { var results = LocalStorageAPI.isResultPresent(scope.query); if (results) { scope.results = results; return; } } var q = { query: scope.query }; ResultsFactory.getResults(q).then(function(response) { scope.results = response.data.results; if (lsAvailable) { LocalStorageAPI.saveSearchResult(scope.query, data.data.results); } }); } } }; }]);
As mentioned earlier, we will check whether local storage is available and then save and fetch the results using the LocalStorageAPI
service.
Similarly, Ionic also provides custom services that we are going to consume. We will take a look at them in detail in Chapter 5, Ionic Directives and Services.
An example of an Ionic service would be the loading service. This service shows a loading bar with the text you have provided. It looks something like this:
$ionicLoading.show({ template: 'Loading...' });
Then, you will see an overlay that is generally used to indicate background activity and block the user from interaction.