0

I wrote a small Angular1 app which has a Database service that is using LokiJS. I was wondering if there is a way to dynamically add properties/functions to a Service/Factory.

I'm trying to add dynamic getter for every collection that is created via this Service.

Here my example:

Database.js

angular.module('MyApp')
  .factory('Database', ['$log', '$q', 'Loki',

      function Database($log, $q, Loki)
      {
        var _db,
          dbInitialized = false;

        function init(config)
        {
            // some logic here
        }

        function addCollection(name, cfg) {
          // some logic here

          _db.addCollection(name, cfg);

          // this doesnt work, but is desired ->
          /*this['get'+name] = this.getCollection.bind(this, name);*/

        }

        function getCollection(collectionName) {
            // some logic here
            return something;
        }

        return {
          init: init,
          addCollection: addCollection,
          getCollection: getCollection
        };
      }
    ]
  );

app.js

angular
  .module('MyApp', ['lokijs'])
      .run(['Database',
        function (Database) {

                Database.init();

                Database.addCollection("MyCollection", {});

                // then fill collection, afterwards ->
                var collection = Database.getCollection("MyCollection");
                // I would like to use Database.getMyCollection()

        }]);;

Is there a way to modify a initialized Service/Factory?

kerosene
  • 930
  • 14
  • 31
  • 2
    The question doesn't explain why `this['get'+name] = this.getCollection.bind(this, name)` doesn't work. If `addCollection` call precedes `get*`, it should work. – Estus Flask Jun 25 '16 at 18:36
  • 1
    Your code should work fine. Do you get any error? – dfsq Jun 25 '16 at 18:42
  • Sorry question was needless... Everything is fine with this['get'+name] = this.getCollection.bind(this, name) – kerosene Jun 25 '16 at 19:31

1 Answers1

1

The most appropriate place for that is decorator

  app.decorator('Database', ['$delegate', function ($delegate) {
            var Database = $delegate;
            Database.init();

            Database.addCollection("MyCollection", {});

            ...

            return Database;
    }]);

The recipe doesn't really differs from run block, but it guarantees that service will be initialized on injection, while run blocks depend on their order.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565