Artful DI in Angular – Part 4: How to Make a Directive that Listens for a Browser Event

In Parts 2 and 3 of this series on Artful Dependency Injection in Angular, we created a service that could look up information about grocery-store produce given a Produce Lookup (PLU) code. Now we are ready to hook it up to a browser event.

Recall this screenshot of our finished application from Part 1:

We have many choices for hooking input of the PLU Code, but let’s go with the simplest for this demonstration. Whenever the PLU Code field loses focus, we will attempt a lookup.

We would like installation of this feature to be as simple as adding an attribute to the PLU Code’s <input>. Assuming the corresponding field in the ProduceLookup record is named plu, we want something like this:

<input id="plu" name="plu" type="text" appLookupKey="plu" />

Given what we have built so far, you won’t believe how easy this is. Here is the appLookupKey directive in its entirety.

Working our way down the source listing, here are some things to notice.

  • We import the abstract, generic LookupService, not the concrete ProduceLookupService. Our directive thus becomes useful for any type of lookup!
  • The selector attribute of the @Directive decorator is [appLookupKey]. This tells Angular that when it comes across an appLookupKey attribute in the HTML, it should wire in our code.
  • An ElementRef is injected into the constructor, and becomes a private property of the class. At execution time, Angular will supply the HTML <input> element to which the attribute is attached. We’ll use it in the @HostListener in a moment.
  • A LookupService (again, this is the generic one) is also injected as a private member.
  • We have an onBlur method decorated with @HostListener('blur'). This is the Angular pattern: to listen for event xyz, make a method onXyz and decorate it with @HostListener('xyz'). More options are in the Angular documentation.
  • In the listener, we call the previously developed LookupService with the value from the HTML element.

To make the directive available throughout the application, we include it in the declarations of the @NgModule decorator of app.module.ts. To give you the gist, here is that module with everything else stripped away.

import { LookupKeyDirective } from './lookup-key.directive';

@NgModule({
  declarations: [
    LookupKeyDirective,
  ],
  // Other, unrelated properties go here...
})
export class AppModule { }

If you create the directive with ng generate directive, that command will do all that for you.

So far, we have said precisely nothing about produce lookups or PLU codes. Everything has been generic. That will change in the next part of this series. In the part after that, we’ll capture the results from the lookup.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.