Improve this Doc

In this step you will learn how to create your own custom display filter.

Let's see what the filter code looks like.

The checkmark Filter

Since this filter is generic (i.e. it is not specific to any view or component), we are going to register it in a core module, which contains "application-wide" features.


app/core/core.module.js:

angular.module('core', []);


app/core/checkmark/checkmark.filter.js:

angular.
  module('core').
  filter('checkmark', function() {
    return function(input) {
      return input ? '\u2713' : '\u2718';
    };
  });
As you may have noticed, we (unsurprisingly) gave our file a .filter suffix.

The name of our filter is "checkmark". The input evaluates to either true or false, and we return one of the two unicode characters we have chosen to represent true (\u2713 -> ✓) and false (\u2718 -> ✘).

Now that our filter is ready, we need to register the core module as a dependency of our main phonecatApp module.


app/app.module.js:

angular.module('phonecatApp', [
  ...
  'core',
  ...
]);

Templates

Since we have created two new files (core.module.js, checkmark.filter.js), we need to include them in our layout template.


app/index.html:

...
<script src="core/core.module.js"></script>
<script src="core/checkmark/checkmark.filter.js"></script>
...

The syntax for using filters in AngularJS templates is as follows:

{{expression | filter}}

Let's employ the filter in the phone details template:


app/phone-detail/phone-detail.template.html:

...
<dl>
  <dt>Infrared</dt>
  <dd>{{$ctrl.phone.connectivity.infrared | checkmark}}</dd>
  <dt>GPS</dt>
  <dd>{{$ctrl.phone.connectivity.gps | checkmark}}</dd>
</dl>
...

Testing

Filters, like any other code, should be tested. Luckily, these tests are very easy to write.


app/core/checkmark/checkmark.filter.spec.js:

describe('checkmark', function() {

  beforeEach(module('core'));

  it('should convert boolean values to unicode checkmark or cross',
    inject(function(checkmarkFilter) {
      expect(checkmarkFilter(true)).toBe('\u2713');
      expect(checkmarkFilter(false)).toBe('\u2718');
    })
  );

});

The call to beforeEach(module('core')) loads the core module (which contains the checkmark filter) into the injector, before every test.

Note that we call the helper function inject(function(checkmarkFilter) {...}), to get access to the filter that we want to test. See also angular.mock.inject().

When injecting a filter, we need to suffix the filter name with 'Filter'. For example, our checkmark filter is injected as checkmarkFilter. See the Filters section of the Developer Guide for more info.

You should now see the following output in the Karma tab:

Chrome 49.0: Executed 4 of 4 SUCCESS (0.091 secs / 0.075 secs)

Experiments

Summary

Now that we have learned how to write and test a custom filter, let's go to step 12 to learn how we can use AngularJS to enhance the phone details page further.