Search code examples
angularjsangularjs-filterangularjs-digest

How to create an angular filter that outputs a unique ID


The question is quite simple, How can you create an angularJs filter that will concatenate any input to a unique ID. This can be very useful for generating HTML id's, or to define unique attribute values for a group of elements in a ng-repeat.

NOTE: The ID must be 'globally' unique which makes angular ng-repeat's $index useless.

Now, the solution that probably comes to your mind is something like this:

myModule.filter('uniqueId', function(){ var idCounter = 0; return function(input) { return (input || '') + (++idCounter); }; });

and in your HTML you write something like:

<div id="{{groupName | uniqueId}}">

The challenge is that angular will run into a digest loop, because evaluating groupName | uniqueId will never yield the same value which means the scope will never settle.

One last thing. We use angular v1.2.27 which means we can't use angular 1.3's new :: (i.e. one time binding) operator.


Solution

  • if you can bind to an object instead of an individual property you could do something like the following:

    check the object for the unique value. if present return it. if not present generate one, assign it and return it.

    myModule.filter('uniqueId', function(){
        var idCounter = 0;
        return function(input) {
            return input.$$uniqueValue || (input.$$uniqueValue = ++idCounter);
        };
    });
    

    Not sure if this exactly fixes you problem but I hope it helps.