0

I am writing a custom filter which involves needing some data map to be initialised so that the data map is not created everytime the filter is invoked.

I do this:

myModule.filter("myfilter", function($filter) {
    return function(letter) {
         // ...
         var blah = myOtherFunction(letter) 
    }
}

var myOtherFunction = function() {
    // initialise some data
    var myData = {
        "a":"letterA"
        "b":"letterB"
    }
    return function(letter) {
       return myData[letter];
    }
}();

This means the file where I define my filter has a utility function which uses a closure to close over data which is initialised once and once only.

I am wondering is there a more angular way to achieve this?

Thanks

More Than Five
  • 9,959
  • 21
  • 77
  • 127

2 Answers2

1

If your data are static, just create a new module/service and inject it in your filter :

myModule.filter('myfilter', ['myService', function(myService) {
    return function(amount, currency) {
        return myService.getLetter("a"); //don't know what you want to do here, using amount or currency I guess ?
    };
}]);


myModule.factory('myService', function() {

    var service = {};
    var myData = {
        "a":"letterA"
        "b":"letterB"
    }
    service.getLetter = function (letter) {
       return myData[letter];
    }
    return service;
});

If your data are retrieved asynchronously, follow this post : Asynchronously initialize AngularJS filter

Community
  • 1
  • 1
Jscti
  • 14,096
  • 4
  • 62
  • 87
1

In general, data should be manipulated/fetched/sent and shared throught services.
But if the "data" you are referring to are:

1.) static and
2.) specific to the logic of the filter

then I believe it does not fall into the general category of "application data"; it is rather "filter logic" stuff.

As such their place is right in the filter.
(BTW, in order to initialize it only once, you don't need all that complex "calling IIFE returned function" stuff. Just put the data in the filter definition function (see below).)

app.filter("myFilter", function() {
    var staticFilterSpecificData = {
        "a": "letterA",
        "b": "letterB"
    };
    console.log('Initialized only once !');

    return function(letter) {
         return staticFilterSpecificData[letter] || 'unknown'; 
    };
});

See, also, this short demo.

gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • Can you confirm everytime the function is invoked the data is not initialised Correct? – More Than Five Jun 05 '14 at 12:21
  • 1
    Yes you can. That's why I added that `console.log` right after the data initialization. If you open up DevTools, you will see that it is called only once. It is the filter function that gets called repeatedly, not the filter initialization function. – gkalpak Jun 05 '14 at 12:42