1

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();
      }
    };

  });
5
  • your code after your first return is unreachable ! Commented Nov 8, 2015 at 21:48
  • Yes! I caught that rookie mistake. I have edited the question to ask how to factor/reuse the code better Commented Nov 8, 2015 at 21:51
  • You have a factory - now you can reuse that factory across you angular app, injecting it into different controllers, where needed. Or what else you want to reuse? Commented Nov 8, 2015 at 22:11
  • What is your specific question? Commented Nov 8, 2015 at 22:19
  • If you look at the functions, list_venue and list_prize, or create_venue and create_prize. They are identical except for the variable they are manipulating. Is there a smarter way to write the function so the code isn't so repetitive? Commented Nov 8, 2015 at 22:24

2 Answers 2

1

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/

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks I'm going to give this a shot as it seems to really reduce the code duplication.
1

i dont know if your familiar with John Papa's angular style guide but you really should take a look it might help you with a lot of design questions. https://github.com/johnpapa/angular-styleguide

anyway - i would recommend you use this approach -

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

.factory('DataStore', function () {

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

  return {
      list_venue: list_venue,
      persist_venue: persist_venue,
      get_venue: get_venue,
      create_venue: create_venue,
      list_prize: list_prize,
      get_prize: get_prize,
      create_prize: create_prize
  };

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

  function list_venue() {
      return venue;
  }

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

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

  function list_prize() {
      return prize;
  }

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

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

i like this approach because on the top you can see all the functions available in this factory nice and easy, and you can also reuse every function you expose outside, inside also, so its very effective and organized, hope that helped, good luck.

1 Comment

I like this approach. It still has me retyping the same code for all the different variables but the organization is far cleaner as you described.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.