Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular services with default values for non-existing attributes

Working on an Ionic application that performs both in Android and Windows.

There are services, such as Ionic's $ionicLoading, which we override functionality in order to work properly in windows:

angular.factory('$ionicLoading', function(){
    return {
        show: function (){...} // custom implementation
        hide: function (){...} // custom implementation
    }
});

But there are other services which we have to override only to not break the app. In this cases it would be really useful to provide a service that won't do anything. For example:

angular.factory('$ionicExampleService', function(){
    return {
        *foo*: angular.noop // for operations
        *bar*: promise // returns promise
    }
});

Note: I know that a better way of doing this would be with a service that chooses between Ionic's implementation or a made one, but this is just for the sake of learning.

The ideal would be going even further, it would be magnificent to be able to return something even more bulletproof. Something like a generic flexible services:

angular.factory('$ionicPopup', function(){
    return /*magic*/;
});

$ionicPopup.show({...}) // show was not defined
    .then(foo); // won't break and will execute foo()

It is possible?

like image 625
fuxes Avatar asked Sep 04 '15 16:09

fuxes


People also ask

What is JavaScript's default object?

Note: Every JavaScript function has a prototype object property by default(it is empty by default).

What are the types of services in Angular?

There are two types of services in angular: Built-in services – There are approximately 30 built-in services in angular. Custom services – In angular if the user wants to create its own service he/she can do so.

Why use services in Angular?

The main objective of a service is to organize and share business logic, models, or data and functions with different components of an Angular application. They are usually implemented through dependency injection.


1 Answers

From what I understood you need to override implementation of existing services. You can do that with an angular service decorator.

A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service.

For more information you can check angular documentation. One simple example would be:

app.factory('someService', function () {
    return {
        method1: function () { return '1'; }
        method2: function () { return '2'; }
    };
});

app.decorator('someService', function ($delegate) {
    // NOTE: $delegate is the original service

    // override method2
    $delegate.method2 = function () { return '^2'; };

    // add new method
    $delegate.method3 = function () { return '3'; };

    return $delegate;
});

// usage
app.controller('SomeController', function(someService) {
    console.log(someService.method1());
    console.log(someService.method2());
    console.log(someService.method3());
});

EDIT: Question - How to override every method in the service?

var dummyMethod = angular.noop;

for(var prop in $delegate) {
    if (angular.isFunction($delegate[prop])) {
        $delegate[prop] = dummyMethod;
    }
}

I hope that this helps you.

like image 171
S.Klechkovski Avatar answered Sep 26 '22 03:09

S.Klechkovski