Wednesday, August 19, 2015

Debugging JavaScript With Chrome’s Developer Tools

While going through this chrome developer tools doc to get a better handle on JavaScript debugging in Chrome, I ran across these:

  1. ESC toggles the console drawer.
  2. Chrome’s version of “step over library source” is to provide a way to Blacklist files. e.g., Blacklisting angular.js would prevent the debugger from stepping into angular.js during the debugging session.
  3. Chrome’s version of “first chance exceptions” is to provide a way to pause on caught exceptions (stop sign with a pause symbol on it, don’t forget to check “Pause on Caught Exceptions”).
  4. Right click a breakpoint to make it a conditional breakpoint.

Setting a Breakpoint when the DOM changes

Breakpoints can be set based on when an element’s DOM hierarchy changes, one of its attributes is changed and when the element is removed from the DOM. These breakpoints can be set through the right click menu on an element (Elements pane, element –> right click –>  Break On). These breakpoints show up in the DOM Breakpoints side panel.

Setting a Breakpoint when a JavaScript event is triggered

This can be done from the Sources panel, Event Listener Breakpoints side panel. All supported events are listed in tree form (e.g., mouse –> mouseout for the mouse out event).

Dealing with Minification

Minification, which reduces the amount of data downloaded by the browser, tends to make JavaScript much harder for human debugging. The {} icon at the bottom of the source pane (Sources panel) is the ‘Pretty Print’ button. The Pretty Print button attempts to de-minify the source.

Friday, August 14, 2015

Custom AngularJS Validation With Inline Formatting

Getting a little further along the AngularJS learning curve. Angular has a built in validation framework (including support for async validators!) but to really take advantage of it angular directives need to be created.

The built in validation provides a very convenient way to conditionally display error messages. There's support for minlength, maxlength, regex patterns and several others new in the HTML5 standard.

Given the following snippet of HTML:

1 <div ng-controller="ExampleController">
2 <form name="form" class="css-form" novalidate>
3 Name:
4 <input type="text" ng-model="user.name" name="uName" required="" />
5 <br />
6 <div ng-show="form.$submitted || form.uName.$touched">
7 <div ng-show="form.uName.$error.required">Tell us your name.</div>
8 </div>
9
10 E-mail:
11 <input type="email" ng-model="user.email" name="uEmail" required="" />
12 <br />
13 <div ng-show="form.$submitted || form.uEmail.$touched">
14 <span ng-show="form.uEmail.$error.required">Tell us your email.</span>
15 <span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
16 </div>
The error messages are conditionally shown based on the built in required and email validators.


I was looking for a way to use something similar, e.g., form.myField.$error.phoneNumber, as the ng-show/if conditional but with application specific validation.


To do this in angular, a directive has to be created. This plunkr demonstrates a custom phoneNumber validator (along with inline formatting, that is, the phone number is normalized upon successful validation). This directive can be applied to a textbox bound to a phone number as folows:


1 <div>
2 Phone Number1:
3 <input
4 type="text"
5 ng-model="phoneNumber1"
6 ng-model-options="{ updateOn: 'blur' }"
7 name="phoneNumber1"
8 minlength="10"
9 maxlength="33"
10 phone-number /><br /> <!-- note: we set maxlength to 33 to allow e.g., 123-456-7890 extension 1234567890 -->
11 <span ng-show="form.phoneNumber1.$error.phoneNumber">The value is not a valid phone number!</span>
12 <span ng-show="form.phoneNumber1.$error.minlength || form.phoneNumber1.$error.maxlength">
13 There must be at least 10 digits in a phone number!</span>
14 </div>

In this snippet the error messages are condtioned on the custom validation supplied $error.phoneNumber. The textbox is decorated with the phone-number attribute which angular uses to apply the validator to this particular field.

Monday, June 22, 2015

AngularJS ng-options: to track by or not

It's been a while but I recently find myself working on a web project using AngularJS. It takes a little while to get the hang of 'thinking' in angular but keeping in mind that it's all about extending HTML makes bridging this conceptual gulf a little easier.

The Single Page Application (SPA) approach makes web development look more like traditional client development in that a lot of state is maintained and manipulated entirely on the client.

One of the core features of Angular is rendering multiple elements of an array (e.g., Orders, Customers, etc...). This can be done with the ng-repeat element or the ng-options attribute to a select list.

With ng-options, if the model backing the selection (the model that stores the currently selected value) is a scalar (e.g., an integral ID, a unique string code, etc...) I've found that using the select as form of ng-options works best. For example, for a dropdown list of customers the model might be a unique customer ID. In this case:

ng-options="customer.customerId as customer.fullName for customer in customers"

allows angular to correctly identify the currently selected customer in the array of customers. This is especially important for models that store previously saved selections.

If, on the other hand, the model is an object (non-scalar), e.g., a customer, then I've found that the label for/track by form of ng-options allows angular to correctly identify the currently selected customer. In this case:

ng-options="customer.fullName for customer in customers track by customer.customerId"

This is handy when the model expects an object for the corresponding property in the underlying Data Transfer Object (DTO).


Tuesday, February 25, 2014

From Startups to MegaCorp: Unlearning to fix everything

In the startup world when you discover an issue, whether it's a logic error or an environmental misconfiguration, being able to fix it quickly and, maybe, document the fix is a virtue.

A hard lesson that I'm learning is that in a different environment that which was a virtue in the startup world can actually be harmful. By fixing an environmental issue you can deprive the organization of the process correction necessary to handle it structurally.

This strikes me as analogous to the decision to *not* handle an error in code. Sometimes you intentionally don't handle an error even though it is anticipated because to do so masks a more fundamental problem. The "if this error occurs, something is deeply wrong in a way that can't be recovered automatically" is a widely established pattern in software construction.

The hard part is realizing that it generalizes to the organizational level. By fixing an environmental issue that another team is responsible for you may well deprive that team of a needed corrective. What happens when you're too busy working on problems that can only be handled by your team and the issue comes up again?

Saturday, February 22, 2014

Expressivity vs Trickle-Down Layering

A basic architectural principle in software engineering about dependencies across layers is that the flow of dependencies should go in a single direction. For example, in a hypothetical 3 layer system composed of top, middle and bottom layers the top layer depends on the middle layer and the middle layer depends on the bottom layer.

If the middle layer reaches back up into the top layer then you've created a circular dependency. Circular dependencies make a system harder to understand (and therefore maintain). One way in which they do this is their tendency to create chicken-egg problems. Put another way, they introduce another axis of dependency (order/time) that may not be obvious from inspecting the code. Chicken-egg problems aren't necessarily intractable, clearly *something* came first, but by adding another dimension they exponentially increase the size of the solution space making for many more blind alleys in which to get lost.

Working on a large system built up over time by many different contributors has given me a much greater appreciation for the importance of this basic architectural principle. This is a bit of a hard-learned lesson because it tends against one of my favorite design principles: the composite pattern. A layer built based on the composite pattern can reference itself as well as lower layers. I'm playing a little loose with the terminology here because layers generally refer to larger pieces of a system while the composite pattern is usually applied to smaller pieces of a large system but bear with me.

Let's take a hypothetical system called Manuals. The Manuals system is maintained by the Manuals team. Manuals depend on Chapters. Chapters depend on Sentences. Sentences are the lowest level of the system - this is where the meat of the work is done. The higher layers (Chapters and Manuals) are primarily about organizing/ordering the work of Sentences.

A few months after the Manuals system ships Developer X encounters it and, being fresh full of ideas about design patterns, thinks it would be really useful if Chapters could be composites. That is, he'd like Chapters to be able to contain Sentences and Chapters. He thinks the system would be so much more expressive that way. And it would enable reuse at the Chapter level. Who doesn't love wringing more expressivity and reusability out of a system?

Fast forward 2 years. Half a dozen developers have rotated in and out of the project each with varying levels of expertise, varying exposure to the original designs and different constituents to satisfy. None of the original developers is still working on it. The design docs, which were originally shared on the shiny, linky (e.g., non-duplicative) intranet were lost long ago somewhere between conversions to Intranet v2 then v3 and now v4 (the current version). Even if they could be found they'd be horribly out of date as the codebase is 10 times its original size. You're tasked with what should be a simple fix: change the wording of a boilerplate sentence that appears in nearly every Manual produced since the project originally shipped.

Being new to the project what do you do? You look at the manuals you can find. You see that each Manual appears to be made up of Chapters and each Chapter appears to be made up of Sentences. So you start your search in the Chapter directory and change every instance of the boilerplate sentence in each of the Chapters.

In a system that maintains the downward flow of dependencies (Manuals -> Chapters -> Sentences) there's a very good chance that this particular bug has been quashed: the boilerplate sentence is updated everywhere it will appear.

But what if Chapters were Composites in the system: they contained both Sentences and Chapters? Although originally all the Chapters were in a single directory, someone once accidentally chose a Chapter name that was already in use (without knowing it) so there was a major refactoring project that moved Chapters contained by other Chapters into other directories. A few months after that refactoring there was a big push to support the creation of chapters by another team. The Manual team just didn't have the bandwidth to handle the demand for Manuals. But the other team stored their artifacts in a different location. So to keep them productive the Manuals team added support for chapter references - pointers to chapters defined in other locations.

Now the job of changing a single boilerplate sentence everywhere it appears has gone from being a grep/findstr in a single directory to a programming task in and of itself. One that crawls Chapter references and looks for boilerplate sentences in the pointed-to Chapters. And doesn't crash on stale references. And doesn't infinitely loop when circular Chapter references are found. All because the downward flow of dependencies was broken when the elegant composite pattern was introduced into the system.

Sunday, December 22, 2013

Upgrading WiFi in a Lenovo T61 ThinkPad to a Windows 8.1 Compatible card via USB Drive

The stock WiFi card (an Intel 4965 AGN) on my ThinkPad crashes every 30 minutes under Windows 8.1 (netwlv64.sys every time).

It also seems not to like the 5Ghz channel (from an Asus RT-N66U) though this was true under Win 7. So I upgraded to an Intel 7260 which is performing flawlessly.

BEFORE Changing the WiFi card

  1. Download the Middleton BIOS iso.
  2. Download rufus from pendrivelinux.com
  3. Follow the instructions at pendrivelinux to format the usb drive as a bootable DOS disk.
  4. Copy the files from the Middleton BIOS iso to the usb drive. (either mount it or use 7-zip to extract the iso contents).
  5. Make sure your battery is near fully charged (battery icon is green not yellow on thinkpad indicator).
  6. Disable the TPM chip in the bios.
  7. Suspend BitLocker if it's on.
  8. Boot from the USB drive.
  9. Run the flash utility (lcreflsh.bat).
  10. Wait for several minutes.

Changing the WiFi card

  1. Follow the instructions here for removing the wifi card.
  2. Insert your replacement wifi card.
TPM can then be re-enabled and bitlocker resumed after rebooting.

Wednesday, December 18, 2013

Upgrading to an Intel Core i7-4770k CPU: UEFI, USB 3 and Windows 8.1

Finally got around to upgrading from an Intel Core i7-920 to a Core i7-4770k. These are roughly 3 processor generations apart (Nehalem microarchitecture to Haswell microarchitecture respectively). As has been their custom for as long as I've been building PCs, the switch necessitated a motherboard upgrade as the 920s used socket LGA1366 while the 4770k requires LGA1150.

I decided to stick with an Asus (pronounced uh-soos) motherboard and picked up their Z87-Plus. The board being replaced, the P6T, was also an Asus board. Come to think of it, so was its predecessor (the A8N-sli). Before that it was an Intel board. Even though I don't do much overclocking I love the attention to detail that Asus puts into its products. And its website is well organized - always easy to find drivers. A few years back a quick comparison of their website to the website of their competitors (Gigabyte, MSI, etc...) sent me flying into their arms. They're not the least expensive boards but I've had good experience with them.

I fallen in love with the front panel header connector they ship with their boards. You plug the front-panel connectors (power LED, reset switch, PC speaker, etc...) into the connector (pictured below) then plug the connector into the board. It's a lot easier to swap out motherboards because you don't have to reconnect the sometimes lilliputian shunts onto single pins.

Front Panel Connector
The processor itself is tiny. Back in the Pentium and Pentium 2 days the processor was huge. Size-wise I recall installing one that was somewhere between the size of an audio cassette and VHS tape (closer to the latter than the former). The processor's these days are not much bigger than a postage stamp though their fans seems to have gotten larger.

CPU and stock fan
One of the reasons I went with the Z87-Plus is that it comes with a UEFI firmware config (aka BIOS). UEFI is the next generation of computer firmware, the successor to BIOS with an emphasis on speed and security. UEFI includes a sophisticated menu system so there's no longer a need for add-on board ROMs to daisy chain prompts and increase the length of time it takes to boot. Beyond that, BIOS writers have richer libraries and greater access to machine resources. The UEFI BIOS on this thing blows me away - it's a mouse-driven modern graphical user interface instead of the standard text based interface that has been a staple of BIOS for over 2 decades.
UEFI BIOS for Asus Z87-Plus
And it displays each of the settings that have been changed in a confirmation dialog before saving them!
UEFI BIOS Confirmation Dialog (apologies for the fuzzy picture)
Performance-wise this thing is a beast. Even though it only has 8 Gigs of RAM Windows 8.1 consistently boots in under 10 seconds. The motherboard itself completes POST so quickly that I've had to turn on a 5 second pause (another nifty BIOS option) so that I have a chance to enter the BIOS if necessary before POST completes. There are all sorts of optimizations this BIOS offers; you can turn off any (or all) of the USB or SATA ports. You can disable initialization of pretty much every connected device. There's something called "hardware turbo" mode that is so fast that I had to turn it off (again because it was nearly impossible to enter the BIOS when POST completes in under a second).

As a pc hobbyist since the mid 90s it amazes me how much easier it has become to build your own PC. I haven't cut myself on an add-on card or connector in going on 10 years. :)