1

I have some main functions I use it here and there in my webApp. These functions are pure JS, no AngularJs related and I want to be able to use them everywhere in my app, because they are helper functions to execute simple tasks.

This is an example of a function I have:

function _removeArray(obj, id) { //Remove object from array
    for(d=0; d<obj.length;d++){
        if(obj[d].id == id){
            obj.splice(d,1);
            return obj;
        }
    };
};

I know we can have some main functions declared inside a service/factory, but is this the best way to declare/use this type of function? Is there a better/corret way to do it?

celsomtrindade
  • 4,501
  • 18
  • 61
  • 116

4 Answers4

2

What I often do is create a global "helper" object:

var h = (function helpers(){
  var output = {};
  output.el = function(id){
    return document.getElementById(id);
  }
  return output;
}());

h.el("myElement");

If you have a whole bunch of functions and variables hanging out in the global scope then that's not a great idea -- but I think having one, with all the functions and variables nested inside it, is extremely useful.

RobertAKARobin
  • 3,933
  • 3
  • 24
  • 46
  • Yes, I do have a bunch of functions, It's a kind of complex app with user and admin area, with restricted and unrestricted areas. – celsomtrindade Jan 13 '16 at 22:51
  • I misspoke. If you put a bunch of functions and variables inside a global object, only that one global object is in the global scope. – RobertAKARobin Jan 13 '16 at 22:53
  • 1
    Oh, yes, I uderstood. But I think using a service is still more organized and cleaner to keep it easy to maintain. I had this doubt because I was reading about AngularJs 2 and Objects in JS, so I tought there would be other way/better way then using a service. – celsomtrindade Jan 13 '16 at 22:55
  • Gotcha. If you want to stay as Angular-y as possible, a service is your best bet. – RobertAKARobin Jan 13 '16 at 23:02
  • Oh yes, at least until 2.0 is out, I'll stick with it. Thanks for your share! – celsomtrindade Jan 13 '16 at 23:04
2

If you don't use any module system with module bundler (like webpack, browserify) or module loader (like systemjs) then yes. For angular1 it is main way to work.

In my app I just created factories like arrayUtils, numberUtils, domUtils, dateUtils and inject them when I need any function from it.

Example:

date-utils-module.js

(function () {
  'use strict';

  /* @ngdoc object
   * @name components.dateUtils
   * @description
   *
   */
  angular
    .module('components.dateUtils', [
      'angularMoment'
    ]);
}());

date-utils-factory.js

(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name components.dateUtils.factory:dateUtils
   *
   * @description
   *
   */
  angular
    .module('components.dateUtils')
    .factory('dateUtils', dateUtilsFactory);

  function dateUtilsFactory(moment) {
    var dateUtils = {
      range: range
    };

    return dateUtils;

    /**
     * Возвращает строку, содержащую текстовое представления диапазона дат.
     * Например (считая, что сейчас 2015 год):
     * <pre>
     * чт, 31 декабря, 17:30 – ∞
       ∞ – пт, 1 января 2016, 21:30
      чт, 31 декабря, 17:30 – пт, 1 января 2016, 09:00
      чт, 31 декабря, 17:30 – 21:30
    * </pre>
    * @param date1 первая дата
    * @param date2 вторая дата
    *
    * @returns строка с диапазоном дат.
    */
    function range(date1, date2) {
      var now = moment(),
          m1 = moment(date1 || null),
          m2 = moment(date2 || null),
          t1 = '∞',
          t2 = '∞';

      if (m1.isValid()) {
        // t1 = m1.calendar();
        t1 = m1.isSame(now, 'year') ? m1.format('dd, D MMMM, HH:mm') : m1.format('dd, D MMMM YYYY, HH:mm');
      }

      if (m2.isValid()) {
        // t2 = m1.isSame(m2, 'day') ? m2.format('HH:mm') : m2.calendar();
        t2 = m2.isSame(m1, 'day') ? m2.format('HH:mm') :
            m2.isSame(now, 'year') ? m2.format('dd, D MMMM, HH:mm') : m2.format('dd, D MMMM YYYY, HH:mm');
      }

      return t1 + ' – ' + t2;
    }

  }

}());
Ruslan Stelmachenko
  • 4,987
  • 2
  • 36
  • 51
  • Yes, currently it's what I'm doing. Since I was reading about ng 2.0, I tought there would be a better way to declare it in pure JS way. But thanks! – celsomtrindade Jan 13 '16 at 23:05
0

You could use a singleton, which is what many JS libraries (such as lodash and Angular itself) do, although this is basically what factories/services allow you to do.

Community
  • 1
  • 1
Samir Aguiar
  • 2,509
  • 2
  • 18
  • 32
0

It wasn't entirely clear if your application is a pure Angular app. If so I recommend you use the standard Angular service or factory pattern. If your application is some kind of hybrid and you are running parts of your app outside the Angular framework then you can just declare all your described functionality using one of the JavaScript module patterns.

var myModule = (function() {
  // private properties and functions
  var privateProperty;
  // public properties and functions
  return {
    publicProperty: ''
  };
})();

Yes you have created a global variable, but you have encapsulated all your functionality in a global object.

Amonn
  • 84
  • 6