Event Unlisteners and Tests

11 views
Skip to first unread message

Joe Allan Muharsky

unread,
Mar 20, 2017, 8:02:08 PM3/20/17
to Angular and AngularJS discussion
I am working on a directive that conditionally listens for events, and logs accordingly.  I'm having an issue with the unregister function, but it seems only during test execution.  In product code, calling the listen function result correctly unregisters the event.  For example, the following code will deregister the listener outside of a test (Jasmine):

this.listener = this.renderer.listen(target, 'click', this.onClick);    
this.listener();

I've distilled the problem down to two Plunkers, one that counts the clicks in tests, and one that counts the clicks on rendered code.  Both plunkers are using the same component/directive code.

Any help is appreciated.  Thanks in advance.

Sander Elias

unread,
Mar 21, 2017, 5:45:17 AM3/21/17
to Angular and AngularJS discussion
Hi Joe,

This is probably an issue in jasmine. I'm sorry, but I currently lack the time to dig into this.
I know this is a test app, but I would program it the other way around anyway, so this would not happen.

  ngOnInit() {    
   
if (!this.unregister) {
       let target
= this.el.nativeElement.getElementsByClassName('target')[0];

       
this.listener = this.renderer.listen(target, 'click', this.onClick);
   
}
 
}

This is a tad more efficient, as it only registers an event listener when it's needed. 
As an added bonus, your test will run.

Regards
Sander

Joe Allan Muharsky

unread,
Mar 21, 2017, 11:39:37 AM3/21/17
to ang...@googlegroups.com
Hi Sandy,

Thanks for the quick reply; the behavior I'm looking for is to allow for runtime modification of the "unregister" bit, which requires toggling in realtime.

Joe

Joe Allan Muharsky
AlphaSource TL | PeopleOps Facilitator
"Stop making decisions for the user based on technology's requirements, and start making decisions on technology based on the user's requirements."

--
You received this message because you are subscribed to a topic in the Google Groups "Angular and AngularJS discussion" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/V4RWlqCzdh4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+unsubscribe@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Joe Allan Muharsky

unread,
Mar 21, 2017, 11:40:23 AM3/21/17
to ang...@googlegroups.com
And understand, the code I provided is not the ideal product code; just a distillation of the issue I'm seeing.

Joe Allan Muharsky
AlphaSource TL | PeopleOps Facilitator
"Stop making decisions for the user based on technology's requirements, and start making decisions on technology based on the user's requirements."

Sander Elias

unread,
Mar 21, 2017, 12:47:27 PM3/21/17
to Angular and AngularJS discussion
Joe,

You are aware that if you check a @input property in ngOnit only gets evaluated once? If you want to react to changes on a property, you can use a @input setter/getter to take care of changes. 
This needs different tests anyway.
And yes, I'm aware that this is a quick one-off to show the problem, but still, it probably reflects the originating code.  Making the change I proposed will make testing and maintenance simpler.

Regards
Sander

Joe Allan Muharsky

unread,
Mar 21, 2017, 12:58:27 PM3/21/17
to ang...@googlegroups.com
Thanks for the recommendation, Sander.  To your point, the provided example doesn't reflect the originating code.  The originating code uses a custom setter on the @Input to toggle the listener.  The examples provided were refactored and optimized for conveying the problematic behavior.

Joe Allan Muharsky
AlphaSource TL | PeopleOps Facilitator
"Stop making decisions for the user based on technology's requirements, and start making decisions on technology based on the user's requirements."

--
Reply all
Reply to author
Forward
0 new messages