9

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?

fuxes
  • 418
  • 1
  • 7
  • 18
  • 6
    This question has a very nice answer here: http://stackoverflow.com/questions/6600868/set-default-value-of-javascript-object-attributes – sunny Sep 04 '15 at 16:04
  • I expanded a bit on Sunny's answer to help it fit the situation. I also removed your -1 rating. -C§ – CSS Sep 11 '15 at 20:27

3 Answers3

4

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.

S.Klechkovski
  • 4,005
  • 16
  • 27
  • The problem is that i want to override everymethod that `someService` has without know his implementation. Something like `$delate.everyMethod = function(){return 'hello world!'; };` – fuxes Sep 18 '15 at 12:30
0

Using an evaluation for each assignment based on an object property, similar to this:

myVar = myObj.myPropVar === undefined ? "default replacement" : myObj.myPropVar;

Basically you're using a check for if the property has been defined, substituting a default value if it hasn't, and assigning it if it has.

Alternatively, you can use a modified version of the global function in Sunny's linkback to define defaults for all those properties you might assume to be undefined at specific points in your code.

function getProperty(o, prop) {
    if (o[prop] !== undefined) return o[prop];
    else if(prop == "foo") return "default value for foo";
    else if(prop == "bar") return "default value for bar";
    /* etc */
    else return "default for missing prop";
}

Hope that helps,

CSS
  • 412
  • 5
  • 17
-3

use var a = {}; to declare new variable.

Oleh Kurpiak
  • 1,339
  • 14
  • 34