Allen Conway's Blog

Exploring all things software engineering and beyond...

The Absence of Pattern Thinking for Web Client Code

With 20 years of experience as a software engineer moving through the stack and using a lot of different languages throughout the years, I've seen a lot of good and conversely poor development implementations. I've also had the privilege of being able to work with languages (like C#) that placed a heavy emphasis as a community in  enterprise development around the mindset of using patterns and practices to make code more readable, reusable, and easier to communicate redundant and repeatable ways of creating applications and services. This has helped me immensely and provided me with a mindset on how to think and truly engineer a well built solution.

The priority of pattern thinking is missing

The problem I've seen over the last 5-10 years as a primarily focused JavaScript web client developer is the absence of this type of thinking. So much of the code I see written is just jammed into a file as a means to an end to complete a needed goal. I think unfortunately the explosion in JavaScript development and rapidly created JS developers due to demand has been partly to blame. I also think there has been so much focus on, "which framework/library," that has had a byproduct of having to learn so much just to get code implemented, that pattern thinking is just not at the forefront. Plain and simple there hasn't been time to organize thoughts or thinking around a sound architectural implementation using known patterns when the web client developer is just trying to get their head above water learning the framework, array of JS libraries, state management, CSS, responsive design, offline capabilities, mobile-like features, new work, enhancements, etc.. This in contrast to more stable back end languages that have had similar implementations going on for decades (albeit with new ways to wrap code or deploy; i.e. cloud) where the tenured experience has helped provide an environment where pattern thinking is much more prominent. I know this to be true, because I've been on that side of the fence as well.

Has it always been this way?

This isn't to say there has never been a focus on pattern for front-end code. Industry leaders such as John Papa were advocating for the module and reveling module patterns with ES5 code years ago, and even today alongside Dan Wahlin to carry the flag for architecting Angular apps and having a mindset for patterns and practices. Therefore a voice does exist from advocates for sound and well written code, but overall I just don't see the concrete evidence as much as I did when working with server-side code in C#/.NET. 

It's time we as a web client community when building enterprise web application push harder to use some forethought into how we implement our code borrowing concepts from known patterns and practices. It's not enough just to cram thousands of lines of code into a monolithic style .js/.ts file. This as an aside is one reason I'm not a huge fan of CSS in JS because it adds to desegregation of code and cramming everything into a single file. I don't consider myself old school to like separation of concerns (SoC), as it's really about organization of thought and practice. Much like the UI web component code we like to implement today with a mindset around segregating code into smaller, cohesive pieces of functionality, we must too apply that same style of thinking to the imperative code we write in JavaScript/TypeScript.

A high-level use case

Let me cherry pick a scenario I see more often than not in Angular. At a high-level speaking broadly, most modern Angular code has a thin service code file that makes an API call, and immediately returns an Observable with the result. The real result is that data is consumed and subscribed to in the component, and all presentation logic, data massaging, and appropriate (or sometimes inappropriate because it's IP) business logic is all done in said component. The result? A massive multi-thousand line big-ball-of-mud that's out of control and really difficult to maintain. It didn't start that way, right? The original MVP implementation was just a simple return and binding of data. However like any software that evolves, so does the need for more code and the initial pattern set forth, is scaled good or bad. In this case bad, and the component is out of control.

What if though something like the Command Pattern (or ideas from it) had be used from the inception? The component only acts as an air-traffic controller of sorts; it doesn't really know how to do anything except direct the traffic. It assembles all needed information, builds up and executes the command on the service where the real work happens (in 1..n services). This pattern also lends itself to creating immutable models in the component and they are only ever changed in the service. The service streams the data from an Observable, and all the component does (with minor exceptions) is bind to the new data. This is a much cleaner approach and a highly repeatable pattern for any experience level. Even if this particular approach seems heavy as you're building a smaller application, knowing patterns and their purpose for use will still lend your design ideas about how to better implement and organize your code. 

In contrast to OO patterns and practices but still with critical and planned thinking at the forefront, we could also use a functional programming paradigm (and patterns specific to FP), and leverage things like pure functions to avoid side effects with a goal of consistency and having more readable and logical implementation. Any of these options are better than the absence of any plan, which results in a poor implementation that's prone to bugs and being difficult to maintain.

In the end we didn't complicate the code, we just implemented it differently for the major gain or readability, reusability, and testability. I liken it to these images I used over 10 years ago when talking about patterns and practices in C#. Both containers below have the same content, but which one would you rather grab to get what you need? The answer is simple; the one that is organized.


The plan forward

The question is how do we learn about these patterns and when to apply them in our code? Well the answer is a combination of getting educated on well known patterns and gaining experience using them. It is however an art, and there is a balance to be had on how to use them most effectively. The cynics hear 'patterns' and sometimes get scared off saying, "that will overcomplicate the code!" There are times I agree. How can I spot the difference? Experience. If you don't have any, learn from others. One of my favorite words in the industry is 'pragmatic.' The ability to know balance in code and when and how to use powerful patterns to aid not hinder code. If the two ends of the spectrum are anarchy and over-architecture we want to be somewhere close to the middle. The problem is in my experience, we're too often close to the anarchy-style of implementation on the web client. I think the crazy saving grace that we back into is that since web client frameworks and libraries have only a 2-4 year tenure on average before some major overhaul, all this bad code is made obsolete before it really begins to stink things up. However during that time period it would behoove us to write code that is implemented with better patterns and practices to help extend the life and make the journey a whole lot easier.




How to Prevent Visual Studio from Compiling TypeScript

If you are building a Single Page Application / JavaScript Web application using Visual Studio, you've probably already run into the overlap between tooling that surrounds npm and the tooling within Visual Studio. As web development moves further away from the bells and whistles needed from the IDE (unlike heavy server-side web technologies like ASP.NET MVC that are heavily dependent upon the IDE), separating a project from these 'features' can be not quite straight forward. While the practice of using Visual Studio for modern web development isn't as prevalent these days with much of the coding taking place in streamlined IDEs like Visual Studio Code, there are still a lot of projects that exist and have a hard time decoupling from Visual Studio, MSBuild, and ASP.NET because of their coupled nature. This process will help in this interim stage while the code is still fully integrated and run from Visual Studio.


One of these tasks is preventing Visual Studio from being responsible for building TypeScript and allowing your tooling (i.e. Webpack, Gulp, Grunt) to be in charge instead. The idea here is that your tooling has been configured to lint, minify, build, concat, bundle, copy, whatever all of your project files exactly as you desire. At this point you don't really need MSBuild involved in transpiling your JavaScript to TypeScript as it would be redundant and often times problematic. To prevent Visual Studio from doing any compilation of TypeScript preform the following steps:

1. Ensure a tsconfig file is added to the project and configured correctly

TypeScript and any build process you are using will work together based on the configuration in tsconfig.json. This file can be hand-rolled from scratch, or may have been generated for your project from a process like ng new and the Angular CLI. You can also generate a default tsconfig file (recommended approach as opposed to creating from scratch) using the following command:

tsc --init

This will generate a default configuration file for TypeScript compilation. Your web-client's code build process will need to point to this file and using it as a driver for the TypeScript compilation behavior.

2. Modify the .csproj project file to prevent TypeScript from compiling

Within Visual Studio, right-click your project and select the option to edit the .csproj file. These options are in a XML format and the following needs to be added:

<PropertyGroup>
   <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
</PropertyGroup>

If you still want MSBuild to handle your TypeScript compilation there are several options that will change the behavior: 


One of the only primary use cases I can think allowing MSBuild to handle TypeScript compilation is for using TypeScript independently of a framework/app like Angular or React when using standalone in an ASP.NET MVC application. Otherwise the native build processes of your front-end stack are much better off being used to build TypeScript as opposed to MSBuild.

State of the Union: Future and Historic Thoughts on WebAssembly, JavaScript, and .NET

With all the goodness happening in the world of WebAssembly it's important to keep an eye on what's happening and how this will positively impact development going forward. In the world of JavaScript there are questions about how the worlds will converge. This maybe in contrast with a portion of the .NET community, which seems at times they don't want it to converge; they want JS dev to be thrown out with the garbage as evidence by the sly remarks toward our community over the years (which as a JS dev I've digested kindly). This sentiment is also supported via the primary description of Blazor:

Blazor lets you build interactive web UIs using C# instead of JavaScript

Although that picture gets clearer as I realize their baby (web in .NET) was called ugly for the last decade so they are salivating for Blazor to feel at home again on the web. (zing!) OK back on track and in all seriousness, Blazor is a rich platform to build modern apps using C#, and I do fully appreciate the excitement of being able to run the same code on the client and server. This is a significant strength in addition to several other bullet points about the stack. 

BTW, I qualify to make these remarks as I've been both a .NET developer and a JavaScript developer, so I've been on both sides of the fence for extended periods of time. Just look at the header image on this blog; it's a legacy Visual Studio logo representing the numerous years I've spent as a .NET developer.

History will show though without JS, the development community as a whole I don't think would be near where they are today and still creating per-platform apps like 15 years ago. The ability to write-once and deploy platform agnostic for the last 10 years is unparalleled until recent advancements. It's historic significance can't be ignored. 

Also there is no hidden agenda here to resist change or remain some kind of isolated JS developer wearing blinders. I'm not that dogmatic in my career path as I've typically moved along with change remaining modern to where mainstream development has gone, and not tried to hang on to a stack out of stubbornness. I'll adopt change as the community does, and always excited about the advancements of the future.

The reality is there is too much momentum in JavaScript development for companies/customers/clients to pump the brakes and change everything. This process is always an evolution. There is also the fact that not all development is greenfield, so the question arises about how to have the best of both worlds (JS and WASM)? 

Being pragmatic and assessing the current landscape, I think the real step forward for folks not purely on a single stack like C#/.NET, or any narrow/single stack for that matter will be a hybrid one (by definition hybrid); at least in the beginning. This is even suggested straight from the horse's mouth: https://webassembly.org/docs/faq/


I feel like bullet points 2 and 3 above will emerge in the 1st 3-5 years as a prevalent way of developing modern web apps. A hybrid approach that uses both JavaScript and compiled WASM modules referenced within to produce performant and modern web applications. The language used to create and target a WASM module will be dependent on the team's experience. 

Here are some interesting examples that do just this:

Angular:

React:

It's important to continually modernize our stack and remain fluid with the direction the community guides us. WebAssembly plays an important role in the future of all types of development. What are your thoughts on how this will evolve?

Using Quokka.js for Real-Time Feedback in TypeScript

I'm always looking for cool VS Code extensions and Quokka.js certainly hits the spot. It provides real-time feedback on JavaScript and TypeScript directly in VS Code in a variety of forms. For example if you're testing some code via console.log, you can get the output directly inline to the right of the code which is awesome.

Once installed, all I needed to do was open the command pallet in VS Code (Ctrl+Shift+P) and select, 'Quokka.js: Start on Current File' as shown below:


After initiating the extension, as seen below I was getting live logging directly in the code.


If there's a value not provided in the scope of the file, Quokka.js obviously can't produce an output and this was expected behavior:


There is quite a bit more functionality offered like code coverage assessment (as it pertains to code execution paths, not unit testing), and a provided value explorer. There is also a Pro edition with additional tools available.

Check out the links below to get started:

Quokka.js
VS Code Extension for Quokka.js

I'm excited about WebAssembly, but not as much about my beloved .NET, Blazor's implementation

As a web client developer these days, I'm sold on WebAssembly and looking forward to it's adoption by the multiple languages that can compile to it. However interestingly one of the things I'm beginning to feel is my personal dislike for the Blazor syntax and implementation. I suppose my multiple years being entrenched in JS/TS with really enjoying TypeScript + the SPA frameworks that have a relatively clean separation of markup (declarative) and logic (imperative) has made me have a bit of dislike for lacing the view directly with imperative view logic like this in Blazor:

@page "/myorders"
@inject HttpClient HttpClient

<div class="main">
</div>

@if (ordersWithStatus == null)
{
  <text>Loading...</text>
}
else if (ordersWithStatus.Count == 0)
{
  <h2>No orders placed</h2>
  <a class="btn btn-success" 
        href="https://www.blogger.com/2404">Order some pizza</a>
}
else
{
  <text>TODO: show orders</text>
}

As a side of humor, to format code blocks on this blog I have to select a 'brush' for the language formatting. Case in point, in the above snippet I wasn't sure if I should have picked HTML, C#, or Blazor.

This is probably because I was never a fan of the classic ASP, MVC Razor, or even Blazor implementations where view logic is interlaced with the markup (for web client code I'd even throw in JSX - as explained here). This doesn't matter a pile of beans really because this is all subjective and has absolutely no bearing on how successful Blazor or any other language targeting WebAssembly will be. I actually love the .NET stack and was carved from that block since the beginnings of my professional career, but I just don't like that particular style of implementation for the web. Shoot for all of ASP.NET's webforms shortcomings, the view overall was relatively clean (keeping logic in code separate from the markup) and pure aside the fact the tags may have been ASP.NET server-side controls but still took the shape of HTML tags (analogous in form to today's custom HTML elements).

I also do not like the JSInterop style in Blazor. You can invoke JavaScript functions from within C#, and that alone is handy I suppose, but messy. The functions you want to invoke must be available on the global scope of windowYuck. JavaScript scope and encapsulation was difficult enough to manage through the years, I'd rather not go back to the days of hanging code off the window object making everything globally available. In 100 level examples this seems fine, but get to 10's or 100's of thousands of lines of code in an enterprise app and this could get ugly.

<script>
  window.MyFunction = (someValue) => {
    //JS code here...
  };
</script>

using Microsoft.JSInterop;
public class JsInteropExample
{
  public static Task MethodName(strings someValue)
  {
    return JSRuntime.Current.InvokeAsync("MyFunction", someValue);
  }
}

I'm probably not alone in my opinions, and that's why I'll be keeping an eye on the ability to use TypeScript as a target for WA. I like JS/TS and am comfortable with it for developing web applications. I feel many client side developers may have a similar sentiment and not want to either learn a server-side language, or just prefer the front-end languages they've been using for years. TS on it's own won't be enough (it's just a language), so it would have to be TS + some web framework (??) and we'll have to wait for the pieces to come together.

To that end I'll keep an eye on things like assemblyscript which is a TypeScript to WebAssembly compiler. It doesn't appear to have the traction some of the other compilers do at the moment, but I'm sure it or something similar will gain momentum as WA picks up and the masses of web developers may not feel like using C#, C++, or Rust.

AssemblyScript: a TypeScript to WebAssembly compiler

AssemblyScript: Status and Roadmap

I'm not counting Blazor out for sure, and it's still going to evolve as it's only an experimental project at the moment. I really enjoy developing in C# so it seems like a great match, but in it's early stages it's rough around the edges and maybe that's just my opinion that's shaped as a front-end developer. I'm pragmatic and will not count out the usefulness of developing on a single-stack and this is where Blazor shines for .NET developers. 

I'd be interested in feedback or thoughts about using TypeScript to transpile to WebAssembly or anything else along these lines, so please feel free to leave a comment and let me know.

Named vs Fat Arrow Functions in TypeScript

When working with TypeScript, it's important to understand some of the key differences between named and fat arrow functions. Let's have a look at a basic class with one of each type of function defined, and also the resulting ES5 that TypeScript transpiles to for a better understanding.

Here is a sample TypeScript class with the two different types of functions.

class MyTsClass {

    private myValue: number = 0;

    myNamedFunction(): void {
        setTimeout(function () {
            console.log(`Inside myNamedFunction, this.myValue = ${this.myValue}`);
        }, 1000);
    }

    myFatArrowFunction = (someValue: number) => {
        this.myValue = someValue;
        console.log(`Inside myFatArrowFunction, this.myValue = ${this.myValue}`);
    }
}

const myClass = new MyTsClass();          
myClass.myFatArrowFunction(1);
myClass.myNamedFunction();

Here is the resulting transpiled ES5 JavaScript.

"use strict";
var MyTsClass = /** @class */ (function () {
    function MyTsClass() {
        var _this = this;
        this.myValue = 0;
        this.myFatArrowFunction = function (someValue) {
            _this.myValue = someValue;
            console.log("Inside myFatArrowFunction, this.myValue = " + _this.myValue);
        };
    }
    MyTsClass.prototype.myNamedFunction = function () {
        var _this = this;
        setTimeout(function () {
            console.log("Inside myNamedFunction, this.myValue = " + _this.myValue);
        }, 1000);
    };
    return MyTsClass;
}());
var myClass = new MyTsClass();
myClass.myFatArrowFunction(1);
myClass.myNamedFunction();

For the purpose of this post, we'll concentrate on (2) main aspects of the code
  1. Where the method is created on the object, and the resulting performance impact
  2. How the this keyword behaves
It's important to understand the differences because there is a performance impact. Notice how the named function on the class is created and attached on the object's prototype. In this manner, the method is stored in memory only one time, as objects created from the same constructor point to a single prototype object. This is the more memory efficient implementation.

Now inspect the fat arrow's function in the ES5 code. Because the method is declared and created in the object's constructor (instance member), it will be declared again per each new instance of this type of object created. This has a memory and performance overhead. As a note, this is the identical resulting behavior to explicitly creating methods within the class constructor in TypeScript.

At this point we might be thinking, "Well that's enough let's just use named functions which will be declared on the object's prototype and be done with it!" There is more than meets the eye and the fat arrow function is quite useful. One of the main advantages is that fat arrow functions lexically capture the context of this in TypeScript. This is critically important in functions that contain callbacks or where re-assignment of instance variables might occur. The former use case is one that we run into often with observable callbacks in say Angular components. You may have run into issues with the this keyword and noticed it wasn't the correct context. The issue is if not using the fat arrow syntax, the context of the this keyword will be undefined. If strict mode isn't enabled, the context of this will be of the window object. If you look in the ES5 tanspiled code, you'll notice this is captured from outside the function body allowing our context to be captured correctly.

var _this = this;

Let's look at the console output from the original code above. Notice in the setTimeout call the use of this. However in this instance it's not the proper context resulting in undefined when accessed. 


The fix is to update the callback to use the fat arrow syntax which will capture the correct context of this

myNamedFunction(): void {
  setTimeout(() => {
    console.log(`Inside myNamedFunction, this.myValue = ${this.myValue}`);
  }, 1000);
}

If we run the code again, we get the console output we expect.


In a TypeScript project with the default configuration of "noImplicitThis": true set in the tsconfig.json file, you'll actually be warned in the IDE of this scenario, " 'this' implicitly has type 'any' because it does not have a type annotation." This would be an indication you need to use the fat arrow function instead.


There are other use cases beyond the ones I'm mentioning here today in regards to the behavior of this with inheritance and calling the parent class as well as other differences. However these are two key areas that should be understood, as I see the usage flip-flop without intent, and developers should be aware of the performance and behavior differences and create the correct type where appropriate. They have separate purposes, so I'm not a fan of just one or the other. Using only fat arrow functions have their performance impact, but shouldn't be avoided all together as they are instrumental on capturing the correct context of this when needed. 

Visual Studio Code Snippet - Triple Slash Directive

Sticking with the theme of my last blog post, Running ES6 Modules Native in the Browser using TypeScript, this post looks at pure JavaScript/TypeScript projects (i.e. NodeJS), that might not be using a framework or module loader, yet still need the ability to reference dependencies from other files. We've been doing this for years using the Triple-Slash Directive like the following:

/// <reference path="./src/ts/myClass.ts" />

In Visual Studio Code I was looking for an extension, snippet, or shortcut to type out the above. Interestingly I came up with nothing. Maybe it's inside another extension I hadn't seen, but rather than look for a needle in a haystack, I decided to quickly hand-roll my own snippet. This is trivial to do in Visual Studio Code. Here is the snippet for a triple-slash directive, and it can be used with the following prefix name: "tripSlash"

{
  "Triple_Slash_Directive": {
      "prefix": "tripSlash",
      "scope": "javascript,typescript",
      "body": [
        "/// <reference path=\"${1:path}\" />",
      ],
      "description": "Triple Slash Directive used for declaring dependencies between files when no module loader is used"
  }
}