Tuesday 24 January 2017

Manual event triggering and event listening in angular


Manual event triggering and event listening in angular


We may come at situation where we need to manually trigger event  on some element or to listen existing events on DOM. This is very easy when we use JQuery . We all have been doing this since long.

Angular comes with Jquery light instead of JQuery .  We still can use JQuery but  not  advisable.  All we stick to JQuery light which comes as default.

In Angular things are simple as you can bind event listener in html template itself  for example ng-click. This  post is regarding situation where we need to manually trigger events or listen some existing events and how to cover that in test cases.

I will cover both manually triggering the event and normal event listener in controller.

Lets say you want to bind key down  to capture some events like CTRL + P or CTRL +V etc..

Use case 1 - Listening to some event listener in angular.

You can do in controller simply by below example. you can see in yellow line. So I covered one use
case that is listening to some event listener in angular.


class Controller {
  constructor( $document) {
    this.$document = $document;
  }

 $onInit() {
    this.$document.on('keydown', (e) => this.handleCtrlP(e));
  }

 handleCtrlP(event) {
    if (event.keyCode === 80 && (event.metaKey || event.ctrlKey)) {
      event.preventDefault();
      this.printPage();
    }
  }

Use case 2 - Manually triggering the event in angular

I will cover by writing the test case for above case. So i can show how to write the test case for the same and can cover second use case.

describe('handleCtrlP', () => {

    beforeEach(() => {
        sinon.spy(controller, 'handleCtrlPOfflinePrint');
        sinon.spy(controller, 'printPage');
        controller.$onInit();
      });

    it('should call printPage method when ctrl p triggered', () => {
        angular.element(controller.$document).triggerHandler({ type: 'keydown', keyCode: 80, ctrlKey:         true });
        expect(controller.handleCtrlP).to.have.been.called;
        expect(controller.printPage).to.have.been.called;
      });

     it('should not call printPage method when other than ctrl p kewdown gets trigeered', () => {
        angular.element(controller.$document).triggerHandler({ type: 'keydown', keyCode: 89,                       metaKey: true });
        expect(controller.handleCtrlP).to.have.been.called;
        expect(controller.printPage).not.to.have.been.called;
      });
});

You can notice how i am triggering the keyDown event with keyCode to achieve ctrl +P event. 
Same way you can trigger wherever you want either in your functional code or test case.

triggerHandler comes with JQuery light in angular.element.  You can trigger event on any html element. Just pass that element in argument. In our case its controller.$document  as we listened ctrl + p event on document element.


Hope this article is useful for Angular and specially for test cases.


Note :  I used ECMA 2015 and Angular 1.5 for coding in above example and Mocha + Sinon + Chai syntax for test cases:

No comments:

Post a Comment