Thursday, June 27, 2019

Keyboard Events in Angular

It's not uncommon to have a form listen for keyboard events. In Angular there are some nifty shortcuts that make this process easy... ish. First, there are some (mostly undocumented) shortcuts you can use to listen for common key press events (like ).
<input matInput (keydown.enter)="doSomething($event)">

I've seen this used (and used it myself) in lots of places. Today I learned you can also listen for compound key press events.
<input matInput (keydown.ctrl.enter)="doSomething($event)">

This isn't documented so I don't know exactly which keys you can listen for or what kind of cross-browser compatibility there is, but I know the two I've got here, as well as the ones I've listed below, work in Chrome 75. If one of the keys you want to bind doesn't work (I tried keydown.add and keydown.+ and neither worked) you can go with a HostListener. These are pretty easy to use, but from what I can tell (and trust me, it would not be the first I'm wrong) they bind to the window and are bound from the initialization of the component until its destruction so I try to be careful with these. If you do want to go this route, here's how you can do it. This listener "hears" the plus sign on the keypad as well as the combination of shift and equal (for the plus sign on the qwerty part of the keyboard).
   1:  @HostListener('window:keydown', ['$event'])
   2:  keyEvent(event: KeyboardEvent) {
   3:    if (event.keyCode ==== KeyboardKeys.Add || (!!event.shiftKey && event.keyCode === KeyboardKeys.Equal)) {
   4:      this.doSomething();
   5:    }
   6:  }

There's an open request for documentation of key binding on Github if you want to go comment on it or see what other people are talking about it. Hopefully they get something put together sooner rather than later because it's much easier to use that than HostListeners.

Friday, June 21, 2019

How to Recursively Walk the Directory Tree

I can't believe I've never written this up before. Like, I literally can't believe it. I swear I did this a long time ago. Oh, well. Whatever.

I frequently need to search all the files in a directory for a specific text value and I always end up rewriting the same code to do it. Well, no more! Here it is. It's based on a sample from Microsoft.

   1: private static void WalkDirectoryTree(DirectoryInfo root)
   2: {
   3:  FileInfo[] files = null;
   4:  DirectoryInfo[] subDirectories = null;
   5: 
   6:  try
   7:  {
   8:   files = root.GetFiles("*.*");
   9:  }
  10:  catch (UnauthorizedAccessException e)
  11:  {
  12:   Console.WriteLine(e.Message);
  13:  }
  14:  catch (DirectoryNotFoundException e)
  15:  {
  16:   Console.WriteLine(e.Message);
  17:  }
  18: 
  19:  if (files != null)
  20:  {
  21:   foreach (var file in files)
  22:   {
  23:    if (File.ReadLines(file.FullName).SkipWhile(line => !line.Contains("search string")).FirstOrDefault() != null)
  24:    {
  25:     Console.WriteLine(file.FullName);
  26:    }
  27:   }
  28: 
  29:   subDirectories = root.GetDirectories();
  30: 
  31:   foreach (var subDirectory in subDirectories)
  32:   {
  33:    WalkDirectoryTree(subDirectory);
  34:   }
  35:  }
  36: }