My Favorite JavaScript Language Feature

Recently on one of the social network feeds, there was a long thread of developers putting their input into the question: “What is your favorite JavaScript feature.”

Most people were putting in things like object destructuring, closures, map-filter-apply, reduce, spread operators, promises, arrow functions, first-class functions, eval, async and await. One person even answered with a code sample and another mentioned the use of closure with a block declaration as a model for scope. A block declaration is the use of the ({ … code … }) structure.

function pwrGen() {
    var i = 0;
 
    return {
        next: function() {
 
            var ret = Math.pow(i, 2);
            i++;

            return ret;
        }
    };
}

var gen = pwrGen();

console.log(gen.next(), gen.next(), gen.next()); // -> 0 1 4

Something that I’ve grown to appreciate is the Truthy and Falsey properties, which I think only one other person among hundreds gave mention to.

Here’s why: because JavaScript is a loosely typed language, it handles certain types of conversions in context of the statement they’re in. This provides a way to do a unary collates, quickly identify value, and quick boolean conversions.

Unary Collation

console.log(true && 'all prior conditions are true');

console.log(false || 'all prior conditions are false');

Is There Value?

if (!!thisVarHasValue) { ...

In this example, we can use the bang operator to quickly convert any variable into a boolean. However, there are some caveats.

Can you handle the Truthy?

As you may have noticed in the prior example, there are two bang operators. The first bang operator changes the variable to a boolean type. The second one reverses that. As a result, if the variable “thisVarHasValue” has a value, it results in a True response … with a few exceptions.

The values undefined, 0, and 0.00 and NaN all produce false values. Empty strings also produce a false value. However, empty arrays and strings of zero values produce a true value.

Quickening

Efficiency is on the mind of any good coder. I like to run small benchmarking programs to get numbers when I haven’t come across other posts that do it. Below is a short program that you can run on JSFiddle. It takes a million rows then iterates through them using a single-bang (falsey) and a triple bang (double-falsey) operator compared to a typical undefined-or-zero comparison.

var a = [];

var div = document.getElementById("answer");

div.innerHTML = !!a;

for (var x = 0; x < 1000000; x++) {

  a.push(x);

}



// [Call to doSomething] took 17399.999999965075 milliseconds.


var t0 = performance.now();


for (var x = 0; x < 1000000; x++) {

  if (!a[x]) {
    a.push(x);

  } else {
    a.push(x);

  }
}


var t1 = performance.now();

div.innerHTML = "Single-bang took " + (t1 - t0) + " milliseconds.";





var a = [];

t0 = performance.now();


for (var x = 0; x < 1000000; x++) {

    if (!!a[x]) {
      a.push(x);

    }
}
t1 = performance.now();

div.innerHTML = div.innerHTML + "<br/>Double-bang took " + (t1 - t0) + " milliseconds.";





var a = [];

t0 = performance.now();


for (var x = 0; x < 1000000; x++) {
    if (!!!a[x]) {
      a.push(x);
    }
}
t1 = performance.now();

div.innerHTML = div.innerHTML + "<br/>Triple-bang took " + (t1 - t0) + " milliseconds.";





var a = [];

t0 = performance.now();


for (var x = 0; x < 1000000; x++) {

    if (a[x] === undefined || a[x] === 0) {
        a.push(x);
    } else {
        a.push(x);
    }
}
t1 = performance.now();

div.innerHTML = div.innerHTML + "<br/>Condition checking took " + (t1 - t0) + " milliseconds.";

The result is somewhat consistent. The double-bang is the fastest, followed by the triple-bang, the single-bang, and finally, the typical condition check:

Single-bang took 3.2000000355765224 milliseconds.
Double-bang took 2.899999963119626 milliseconds.
Triple-bang took 3.000000026077032 milliseconds.
Condition checking took 3.2999999821186066 milliseconds.

But remember, this is across a million rows. a tenth of a millisecond doesn’t amount to much. This was an exercise to see if there was something substantial to use in optimizing code and to peek into the JavaScript engine’s behavior.

What I find interesting is how the triple-bang, which is the same value as the single-bang, is somehow just slightly faster. I’ll have to do a follow-up later as to why this is the case.

A Little React Fun

Here’s a game that I created where you pick a movie with the highest iMDB rating… and some things I learned making it.

Click Here to Play the React Christmas Movie Quiz!

I enjoy tinkering around with different technologies, and where I sit today, most businesses want React. I looked into it a little over two years ago, but Angular 2 was the hot number, so my focus was on that at the time. Over the Christmas weekend, I cracked open some Pluralsight videos, blogs and pieced together a fun little quiz application.

It lacks the polish I would have liked, but there’s enough in place to demonstrate that I’ve learned a few things and had fun at it.

Rather than going into the standard talk about React mojo: bindings, scope, virtual DOM, functions, classes, ES6, TypeScript, etc. I’m just going to go over a couple of specific areas that I got stuck on and found interesting.

  1. Use setState instead of your typical assignment when applying changes to the state.
  2. It’s very Dependency Inversion based. Pass the method definitions from the highest level (where your state is) down.
  3. Those aren’t HTML tags, they’re JSX. They’re a shortcut to the mojo.
  4. If something isn’t updating, check the context of your props.

And some not-so-technological stuff I learned:

  1. Give the user some context for the data. At first, it didn’t load thumbnails. It loads them, but they’re still too small. Nevertheless, there’s a reason why icons are so popular. They give us context.
  2. Give the user some reference for the data. Like the thumbnails, the app didn’t used to show the IMDB link after the user made their selection. There were quite a few times when a movie popped up and I thought “Hey! What’s that movie about?” Now I have a way to learn.
  3. Don’t stuff the interface with data. I also had the list of actors, synopsis, rating, etc. That was way too much information that just cluttered up the UI. The user might still want that information to make their pick, but it’s meta. It’s auxiliary. In short, it’s unnecessary.
  4. Form is not function. My laptop dumped my changes because of Apple’s Touch Bar. Nice little invention if it’s needed, but because my knuckle hit a little virtual button, a day of tinkering was lost. I found several other strong rants from developers against the Touch Bar, which ensured me that I was in good company with my frustration.

Click Here to Play the React Christmas Movie Quiz!

So what’s next regarding this app? I have a list of features and behaviors that I’d like to see. What I add into it depends on the time I have and the priority to tinker and learn. I showed the current product to a friend of mine who has a good eye for UI and she pointed out some overall design changes which we sketched out:

The list below is incomplete and isn’t in any particular order:

  • UI looks rough. Clean it up as follows:
    • Change input from lines to boxes. This will improve spacing and provide more real-estate to the movie poster images.
    • After each answer is selected, provide a “Next” button instead of a “Play Again” until all 10 questions have been picked.
    • Show the number of correct and incorrect answers with colored icons and the number of remaining questions with a grey one. For example, use little colored elf shoes for correct answers, black elf shoes for wrong answers and grey outlines for those not answered yet.
    • Show larger thumbnails with little text beneath.
    • In the little text beneath the posters, show an iMDB badge that the user clicks on to go to the site instead of the current text. Also show the rating on the upper-right corner of each block in a circle.
    • When a poster is not available, show a generic greyed out “Poster Not Available” image.
    • Do better in filtering out the embarrassing movie titles that sometimes show up. (either an IMDB ID filter or a title filter).
    • The “Play Again” button only shows after all 10 attempts have been used up, effectively restarting the game.
    • Better colors for hovering, for correct answers and for incorrect answers.
    • Add a little “X” or Check mark for wrong/right selected answers.
    • Hold the space for the movie blocks so that the items on the bottom of the screen don’t jump up to the top while the next round is being pulled from the web service.
    • Put a placeholder for the movie blocks while their promises are getting filled, then populate them with the actual content.
    • Perhaps add a “Skip” button?
    • A Cleaner and more modern representation of each movie block.
  • A final rating from 0 (“Cotton-Headed Ninny Muggins”) to 10 (“Santa Clause Prodigy”) and every variant of Elf-isms in between (taken from my wife’s favorite holiday movie, Elf).
  • A top-score billboard. (Let the user enter in a few characters, but scrub it for profanity).
  • Make the product take “themes”. Themes would direct the engine to certain types of movies (e.g. “Musicals”), color schemes and icons, and top-score tables.
  • Allow the user to select which “theme” to play.
  • Download the values from the OMDB system into a local MySQL database and create a back-end PHP page that mediates the requests. This would allow me to get around the 1,000 request limitation and filter out crazy films from the game.
  • Allow user to change the game from using the iMDB rating to using Rotten Tomatoes.
  • Put a title and instructions at the top of the game board.
  • Add an informational badge within each movie block that allows user to see the actors and plot line. (Which year was that Christmas Carol with Patrick Stewart?)
  • Offer a secure feedback form as a fresh pop-up from a link on the game page so people can make suggestions without this blog getting injected with a hack-job.
  • The list could go on, but I think I’ve touched on the main faults and hit a few extra “nice-to-haves” in this existing list.

Part of software design with unfamiliar technology is to throw something out there, get a feel for what works and what doesn’t, then either rewrite or build upon what you’ve got. There were a few throw-aways while I built the current game and one accidental code loss that forced me to rewrite about a third of the code. But I learned a good deal, and am proud of what I learned far more than the current state of the movie game.

Nevertheless, I hope you have fun with it. If you have any questions as to its design or have any suggestions – please drop me an email.

Cheers!

What I Learned Spending A Month With InstallShield.

InstallShield by Flexera is a packaging development tool that, through a combination of settings and scripts, produces an installer that aids in distributing your software and setting up its prerequisites.

Other developers throughout my company would snicker when mentioning InstallShield after hearing that I was assigned to a project that upgraded our distro from version 2012-Spring to 2016. Though I won’t scoff at the product, it posed certain challenges that it shouldn’t have.

Challenge 1. How to learn it

There is no book

At least, there is no recent book. The latest one on Amazon is from January 1st, 2004. That’s 14.5 years old, and InstallShield has changed quite a bit since then. Windows XP was the latest operating system at that time.

To put that in perspective, YouTube wouldn’t exist for another 2 years. Heck, Facebook didn’t even exist!

I didn’t buy the book.

There are no inexpensive online courses

Pluralsight? Nothing. Lynda.com? Nope! LinkedIn Learning? Nada…

There’s very little free content out there to guide someone who has never used InstallShield from a developer standpoint.

There is, however, a $2500 class offered by Flexera to teach the basics – basics that don’t cover the type of installation project I was faced to upgrade and debug.

Their Online Help is Problematic

Some people might claim that InstallShield has good online documentation. I disagree. There aren’t enough examples and some of the InstallScript’s language statements, like “external” even tell developers not to use it (“The keyword external is reserved and may not be used.”), even though it’s required to reference other library packages and scripts that extend the functionality, as detailed in their blogs (“Functions that can be called by a Suite/Advanced UI action [and by InstallScript custom actions in Basic MSI projects] must be prototyped with the export keyword.” *Using InstallScript Actions in Suite/Advanced UI Projects*). At the time of this article, Flexera’s entire helpnet server is down, so users trying to find help on their InstallScript API are dead in the water was given an impressive update that helps put much of its InstallScript in context.

Still, when you can access their documentation, it’s terse description, lack of examples and blatent misleading elements make development in InstallShield a chore. Hopefully this will improve over time, given that they’ve just invested time and money with the recent roll-out of site improvements and see it as a priority in a growing market.

Learning about a feature or how an API command is used requires the build-measure-learn method (or experiment-fail-learn) with a lot of failure in its cycles. The trick to this is to fail fast and fail early. Failing often will just come naturally because so much experimentation is involved.

Learning and Help is Only from Generous 3rd-Party Release Developers

There are some blogs and StackOverflow threads that were very useful, but each post is specific to a feature, not the overall use of the product.

The most helpful of these are:

Surprisingly, StackOverflow wasn’t very useful. When you look at questions tagged with “InstallShield”, there’s about a 50% answer rate and a 4% accepted answer rate, which was the same rate as down-voted questions. In my personal opinion, people are down-voting legitimate questions because they don’t have the experience or understanding of InstallShield and thusly don’t see how the question is related. But there’s all sorts of trolling on StackOverflow that I won’t get into right now. That’s a topic already addressed on other blogs.

Challenge 2: Versatility

The more features a software product provides, the more complicated it is to use. This is why simple systems, such as the basic calculator in your operating system, are first offered to consumers instead of feature-rich systems, such as a programmable calculator.

Installshield states that it has 3 different types of projects, but it’s documentation specifies 12 types of projects:

  • Advanced UI
  • Basic MSI
  • DIM
  • InstallScript
  • InstallScript-MSI
  • InstallScript Object
  • Merge Module
  • MSI Database
  • MSM Database
  • QuickPatch
  • Suite/Advanced UI
  • Transform
  • Visual Basic .NET Wizard
  • Visual C++ .NET Wizard

The point I’m making here is that their documentation is confusing about what you can do with InstallShield. After spending time in it, I’ve become aware that it can do quite a bit. It’s very versatile, but its functionality is compartmentalized and, as I’ll bring up later, one project’s ability doesn’t share across to annother’s. There are three overall categories of projects (Basic MSI, InstallScript and InstallScript-MSI) but within those, you can chose variations and build them to certain specifications to handle its various 3 tasks: installation, maintenance and uninstallation.

Getting a feel for what it can do takes time for experimentation and going over documentation where you can find it. There are some “walkthroughs” on Flexera’s site, but they hardly substitute for a good YouTube video. It’s just text telling you what to do, but not giving you context as to where to find it. For example, you might read something like this from the top of their help pages:

note_project Project • This information applies to InstallScript MSI projects.

Pay close attention to this. They didn’t exist before (or at least they weren’t formatted to make them so visible before) their HelpNet update. This can save you hours of time because the InstallScript MSI and the InstallScript (non-MSI) projects do not share the same API library.

The company I work for used InstallScript-MSI, which is a mix of configuration throughout the various project areas and InstallScript code that resembles JavaScript or C# syntax to a small degree. In that mindset, you tend to think that an API is an API, but that’s not the case with InstallShield.

For example, in the InstallScript-MSI projects you use SQLRTTest whereas in the InstallScript (non-MSI) projects you use SQLRTConnect2. Neither project type can view the others’ SQLRT library. In this case, the methods are nearly identical; it would have been nice if Flexera’s API showed some consistency here. But before their HelpNet update, it was difficult to discern which of the two APIs you were looking at, which meant I spent several hours trying to make SQLRTConnect2 work on a project that wasn’t designed to handle it.

Challenge 3: puffed-up expectations

“What’s taking you so long?!” one of the managers in my department began. “We don’t have the budget for this. We needed to just spit some installer out and get on with the features our clients care about – the stuff they’re paying us for.”

To one extent, he’s right. The installer is just a brief, 10-minute experience compared to the hours the client spends in the product… however, it turns out we sell a product that is so difficult to install (and uninstall) that the clients are getting frustrated. To make matters worse, this product was never meant to be a main feature of our organization; I don’t think we even charge for it, but our sales department in desperation to sell more hardware suddenly felt that pointing out this free software will let them do all the heavy lifting they’re wanting to do. Now we have a department pushing this weaker product to clients instead of the strong, and intended, software to configure the hardware components. That means we’ve suddenly gotten a surge of clients trying to install a product that has defects the first minute they try to install it.

Managers sometimes think that if you spend $6,000 to $10,000 per license on a product that it shouldn’t cost much to use it. What makes it worse is that because the program is so expensive, the company I work for only purchased one license, so all developers have to log onto one machine and do our work there… and that happens to also be the build server! Great care has to be done to sandbox the development from the build.

The rules are shared. This is critical to know. When you set prerequisites for the installer, you specify a set of rules. Operating system rules are matched as an OR operator. All other rules (such as registry settings and file versions) are matched as an AND operator. So if you create a rule such that you install a patch on Windows 7, 8 and 8.1 (but not on any other OS) if (and only if) a certain registry key exists and a file exists at a certain location, you’d create a rule with 5 conditions: 1 for each of the three operating systems, 1 for the registry and 1 for the file.

If a rule is faulty – say it’s installing when it shouldn’t because there’s a misunderstanding about where the key exists – then just by saving the rules file, the build server starts using it. And it uses it for regression builds, so if I am currently on version 2.2.2 and I need to patch version 2.1.7, the new build of version 2.1.7 will include the changes to the installer’s rules but not to anything else, so a script that requires a different prerequisite ruleset would actually require a fully separate prerequisite install. There’s no isolation. When you save a rule you save it to the entire InstallShield instance on that machine – not to your project.

So there’s a significant amount of time overhead to plan and develop in a way that doesn’t impact our build. What was originally estimated to be a 7 day project ended up exploding into a 21 day project to accomodate the steep learning curve, the unpleasant discoveries, navigating the (then) misleading documentation, and the poor “money-saving” configuration. I was overly optimistic because of the expectations from higher level developers and/or management that this “shouldn’t take long”. Though now that I reflect on their comments I think it was more a statement of what they wanted rather than one of experienced anticipation. The last time the InstallShield projects were touched was three years ago, which implies that it was such a pain then that nobody wanted to touch it. That developer has left the company since then, so we couldn’t expedite the development from his experience. Maybe if he was still around, we could have utilized his experience and it actually would have taken only 7 days. With what I know today, I think I could work out the changes and upgrades the company wanted within that time period.

I think it’s safe to say that more expensive products require more training to utilize them. Photoshop isn’t cheap, and takes a couple of weeks to learn well enough for rudimentary photo touch-up and post-processing. It takes years to know well enough to navigate through the app with confidence and to identify the best way to process certain effects. The product our company creates is complex and takes weeks to learn most of its features. InstallShield appears to be no different in this matter. The main difference here is that InstallShield creates a product that people use for a couple of minutes, then it’s done. And unless something goes wrong with the install, you never really think about it. Whereas with Photoshop and enterprise products, you spend so many hours within it that there is that sense of pay-out, so development cost expectations are justified.