Search code examples
angularjsionic-frameworkangularjs-factory

How to reuse functions in an AngularJS factory?


I have an AngularJS factory for some common local storage manipulation. It's a common set of functions against different variables. I am constructing it so that the functions are repeated depending on which variable needs to be manipulated. Likely not an elegant way to go about this so open to options.

The factory looks as follows. Is there a way to reuse functions depending on the variable without so much code bloat?

angular.module('app.datastore', [])

  .factory('DataStore', function() {

    var venue = angular.fromJson(window.localStorage['venue'] || '[]');
    var prize = angular.fromJson(window.localStorage['prize'] || '[]');

    function persist_venue() {
        window.localStorage['venue'] = angular.toJson(venue);
    }

    return {

      list_venue: function () {
        return venue;
      },

      get_venue: function(venueId) {
        for (var i=0; i<venue.length; i++) {
          if (venue[i].id === venueId) {
            return venue[i];
          }
        }
        return undefined;
      },

      create_venue: function(venueItem) {
        venue.push(venueItem);
        persist_venue();
      },

      list_prize: function () {
        return prize;
      },

      get_prize: function(prizeId) {
        for (var i=0; i<prize.length; i++) {
          if (prize[i].id === prizeId) {
            return prize[i];
          }
        }
        return undefined;
      },

      create_prize: function(prizeItem) {
        venue.push(prizeIem);
        persist_prize();
      }
    };

  });

Solution

  • My approach is to return in the factory a function which will return a store of a type (venue, prize, ...)

    angular.module('app.datastore', [])
        .factory('DataStore', function () {
    
        var getStoreFunction = function (storeName) {
            var store = angular.fromJson(window.localStorage[storeName] || '[]');
    
            function persist() {
                window.localStorage[storeName] = angular.toJson(store);
            };
    
            return {
                list: function () {
                    return store;
                },
    
                getItem: function (id) {
                    return store.find(function (elem) {
                        return elem.id === id;
                    });
                },
    
                createItem: function (item) {
                    store.push(item);
                    persist(store);
                }
            }
        };
    
        return  { getStore : getStoreFunction };
    });
    

    you can create unlimited store by using

    var venueStore = DataStore.getStore('venue');
    //use of your store
    venueStore.createItem({
        id : venueStore.list().length + 1,
        name : 'myVenue' + venueStore.list().length + 1
    });
    $scope.venues = venueStore.list(); 
    

    you can create a factory per type if you want or use it directly in your controller as in this example : https://jsfiddle.net/royto/cgxfmv4q/