Saturday, February 11, 2017

The folder structure requirements for Angular 2 in a C# MVC application are a little finicky.

Do not put the Angular stuff in the Scripts folder with all of the other random JS stuff. It needs its own folder at the root of the UI project and this folder cannot just be named anything. The folder needs to be named after the Controller that will cough up a view that uses it! That means in the case of HomeController your Angular app will go in a "Home" folder in the root of your UI project with the "app" and "node_modules" folders immediately inside of it and in the case of WhateverController your Angular app will go in a "Whatever" folder in the root of your UI project with the "app" and "node_modules" folders immediately inside of that folder. It might be best NOT to use the HomeController and to instead make something new honestly. Consider these three URLs:

  1. http://localhost:60892/Home/Index
  2. http://localhost:60892/Home
  3. http://localhost:60892

Alright, the first two will work great with an Angular app in a "Home" folder and the third will barf red up to Google Chrome's console instead of behaving itself. That's frustrating! I hacked around this problem by making the HomeController automatically redirect to a different controller and then using that controller to fish for the view for the Angular 2 mechanics. The Home Controller just looks like this now:

using System.Web.Mvc;
namespace MyApp.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         return RedirectToAction("Index", "Whatever");
      }
   }
}

 
 

In the view that actually summons the .js files for Angular code you should craft URLs like so:

<script src="~/Whatever/node_modules/core-js/client/shim.min.js"></script>

I don't know what to do with the elephant in the room.

By elephant I mean: big heavy thing. Here some thoughts on the fatso node_modules folder which for this little project holds 89.9 MB and 10,559 files. But these are just thoughts and not solutions. I'm trying to figure out what is best to do. If you add this sort of thing to source control or add it to a Visual Studio 2017 RC solution you will see the proverbial spinner spinning a little bit. In the case of including in it a .csproj file, you will quickly find that you can't compile as there will be one hundred and one things (well, twenty-four without hyperbole) nested in third party gunk the TypeScript compiler hates. Putting <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked> inside the first <PropertyGroup> in the .csproj file will stop TypeScript compilation when you build. This means no TypeScript compilation from within Visual Studio, but maybe that's not the end of the world. I don't see why I can't build (and thus sanity check) TypeScript at the command line. Why does everything work there and not in Visual Studio? Well, I suppose that is another puzzle. I guess it's trendy to have an Angular 2 frontend that one just works with in Visual Studio Code that merely talks to C# through REST calls effectively putting the C# and the TypeScript in two entirely different applications. And yet, that begs the question: "What if you want to mix Angular 2 into a traditional MVC app?" With regards to source control, it's gonna be painful to tuck node_modules away if it actually gets updates regularly. I guess you would start out hoping that such isn't the case. Not keeping a copy in source control could lead to some terrible, terrible surprises when you pull the code two years later and try to rehydrate the folder only to find that newer versions of libraries introduce devastating changes. I don't know what to do about any of this.

It's a gamble either way, right?

Friday, February 10, 2017

Just what does type in TypeScript do exactly?

Alight kids, this TypeScript...

enum ColorPattern {
   Solid,
   Splotchy,
   Striped
}
 
class Snake {
   commonName: string;
   genusAndSpecies: [string,string];
   lengthInMeters: number;
   appearance: ColorPattern;
}
 
class Constrictor extends Snake {
   poundsPerSquareInchPressureFromSqueeze: number;
   shouldYouRunIfYouSeeOne: boolean;
}
 
class HarmlessSnake extends Snake {
   recommendedAsPet: boolean;
}
 
class Viper extends Snake {
   lethalDoseFiftyScaleRating: number;
   milligramsOfVenomPerBite: number;
   shouldYouRunIfYouSeeOne: boolean;
}
 
type DangerousSnake = Constrictor | Viper;
 
interface AdviceDangerousSnake {
   give: (serpent: DangerousSnake) => string;
}
 
let advice = <AdviceDangerousSnake>{
   give: (serpent: DangerousSnake): string => {
      if (serpent.shouldYouRunIfYouSeeOne) {
         return `Run if you see a ${serpent.commonName}.`;
      } else {
         return `Freeze if you see a ${serpent.commonName}.`;
      }
   }
}
 
let tuple: [string, string] = ["Eunectes", "murinus"];
 
let anaconda = new Constrictor();
anaconda.commonName = "Green Anaconda";
anaconda.genusAndSpecies = tuple;
anaconda.lengthInMeters = 5;
anaconda.appearance = ColorPattern.Splotchy;
anaconda.shouldYouRunIfYouSeeOne = true;
anaconda.poundsPerSquareInchPressureFromSqueeze = 65;
 
alert(advice.give(anaconda));

 
 

...is pretty verbose considering that all it does is throw an alert with "Run if you see a Green Anaconda." in it, but, well, it's an excuse to show off TypeScript! TypeScript compiles to JavaScript and per https://www.typescriptlang.org/play/index.html it will ultimately make this JavaScript if the above is given...

var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var ColorPattern;
(function (ColorPattern) {
   ColorPattern[ColorPattern["Solid"] = 0] = "Solid";
   ColorPattern[ColorPattern["Splotchy"] = 1] = "Splotchy";
   ColorPattern[ColorPattern["Striped"] = 2] = "Striped";
})(ColorPattern || (ColorPattern = {}));
var Snake = (function () {
   function Snake() {
   }
   return Snake;
}());
var Constrictor = (function (_super) {
   __extends(Constrictor, _super);
   function Constrictor() {
      return _super.apply(this, arguments) || this;
   }
   return Constrictor;
}(Snake));
var HarmlessSnake = (function (_super) {
   __extends(HarmlessSnake, _super);
   function HarmlessSnake() {
      return _super.apply(this, arguments) || this;
   }
   return HarmlessSnake;
}(Snake));
var Viper = (function (_super) {
   __extends(Viper, _super);
   function Viper() {
      return _super.apply(this, arguments) || this;
   }
   return Viper;
}(Snake));
var advice = {
   give: function (serpent) {
      if (serpent.shouldYouRunIfYouSeeOne) {
         return "Run if you see a " + serpent.commonName + ".";
      }
      else {
         return "Freeze if you see a " + serpent.commonName + ".";
      }
   }
};
var tuple = ["Eunectes", "murinus"];
var anaconda = new Constrictor();
anaconda.commonName = "Green Anaconda";
anaconda.genusAndSpecies = tuple;
anaconda.lengthInMeters = 5;
anaconda.appearance = ColorPattern.Splotchy;
anaconda.shouldYouRunIfYouSeeOne = true;
anaconda.poundsPerSquareInchPressureFromSqueeze = 65;
alert(advice.give(anaconda));

 
 

So there are few supertypes, if you will, in C#: class, interface, struct ...and TypeScript has a few supertypes too: class, interface, type ...a class being like a class in C# more or less, but an interface being very different. You can just make a variable from an interface as you can a class. The only differences are:

  1. that interfaces must be instantiated with a bit different syntax and at that moment all of the required fields must be hydrated and that's any field that doesn't have a question mark both immediately after its name (no space) and before the colon before its type
  2. a class can have methods but an interface only may have signatures for methods making them comparatively anemic

Classes may implement interfaces and what is more interfaces, yes, may implement classes. This will make your head want to explode until you eventually get used to the idea that "interfaces" are just a very different thing in TypeScript than they are in C#. An interface can be a contract to upcast a class to, but then again you don't really need a class to use them so don't think that's what they are for, all in all. There is no inheritance for type. You can just make a type like so:

type DangerousSnake = {
   commonName: string;
   genusAndSpecies: [string,string];
   lengthInMeters: number;
   appearance: ColorPattern;
   shouldYouRunIfYouSeeOne: boolean;
};

 
 

But the real intent of type seems to be to alias classes like so:

type DangerousSnake = Constrictor;

 
 

Both of the versions of DangerousSnake immediately above could replace this line of code at the beginning of our blog posting...

type DangerousSnake = Constrictor | Viper;

 
 

...and the code would still successfully compile to JavaScript and the "Run if you see a Green Anaconda." alert would still fire when JavaScript code was generated, but things get a little more interesting when we introduce a pipe symbol to alias two classes. This allows for something on par with "where T" in C#'s generics. The pipe means intersection and our type will have fields common across the two classes that hydrate it as seen at this screen grab from the TypeScript playground:

 
 

Replacing the pipe symbol with an ampersand allows for a union instead of an intersection and all fields across all classes are available. You will need to be a little more careful with these, obviously.

 
 

Addendum 10/4/2018: An interface in TypeScript will make nothing when compiled to JavaScript. It provides type safety in TypeScript and nothing more. Notice above that AdviceDangerousSnake does not exist in the JavaScript.

how to make a photo for yourself in the Outlook-2013-with-Exchange paradigm

  1. open Outlook 2013
  2. click "People" at the bottom where it says "Mail Calendar People Tasks"
  3. at the list of People, Business Card, Card, Phone, List at the top nav go to People and search for yourself
  4. add yourself to your People list
  5. go to Business Card and open your own Business Card
  6. click on the photo within the Business Card to change it up
  7. you'll upload a new photo

when your iPhone asks if you want to switch to low power mode and you accidentally say yes

To turn this back off on a phone like mine, an iPhone 45 with iOS 9.1 (13B143):

  1. go to: Settings > Battery > Low Power Mode
  2. uncheck

Thursday, February 9, 2017

what the "Controller As" pattern is and what it's not

$scope in the old AngularJS 1.58 paradigm may seem at first glance like a guiding light, a beacon to gravitate towards, a thing to stray towards by default in lieu of straying off elsewhere...

...but once you get a closer look it's a little scary!

You are being drawn into a dangerous web with its overuse. I was originally under the misimpression that the "Controller As" pattern would restrain $scope to the scope of a controller rather than letting it be application-wide, but that is not the reality. The pattern just gives you convenience names to use in markup and the as keyword does not really even have to be restrained to a controller either.

<div ng-controller="ArachnidController as spiderWeb">
   {{ spiderWeb.intro }}
   <div ng-repeat="spider in spiderWeb.arachnids as spiders">
      {{ spiders.$index }} - {{ spider.name }}
   </div>
</div>

 
 

Above $scope.intro gets replaced with spiderWeb.intro but who cares? This actually does not reduce the scope of $scope. I was confused to think that there was an application-level $scope above what $scope means at any one controller. Indeed there may be such an animal, but it is at the controller level where $scope grows fat (as a controller grows fat and gets dozens of variables hanging off of $scope) and this a big enough problem by itself, a major performance pain in the first version of Angular, to raise alarm. It is not something you can fix with the "Controller As" pattern. Angular 2 deals with this well by more modularly breaking things up in components instead of having a controller approach that turns into a spaghetti mess as an app grows significantly not trivial. It does help a little that controllers are isolated from each other and if you want crosstalk data between controllers you need to do it through a service. Similarly, if some things on a controller's $scope are not strictly needed maybe they could be nested in a directive that is only conditionally brought to life. The really painful thing is that every variable in $scope has a watcher associated with it running in the background as an agent for reacting to change detection. $scope is basically like this+ with the plus part being that all the items hanging off of the "this" each get a watch, so in a controller $scope is scoped like this for the controller, and down at a directive there is some isolated $scope restricted to the bounds of just the directive. I guess you can see how $scope.intro and spiderWeb.intro and, for that matter, this.intro are comparable in ArachnidController, no? The watchers alone distinguish the first two from the third item. The anti-pattern of just packing things on $scope will lead to lag and what is more there may be digest cycles in which items on $scope update other items on $scope that are calculated values, exasperating things exponentially. Changing something like this...

$scope.foo = 13;
$scope.bar = 42;
$scope.baz = 69;

 
 

...to something like this...

$scope.qux = {
   foo: 13,
   bar: 42,
   baz: 69
};

 
 

...is a good way to make an optimization. Now three watches have been reduced to one. A flag at the qux object, such as changing the baz to 86, will get caught by the watchers. The watchers do not just watch to see if a pointer is similar or different on a JSON object. They are somehow crawling the object for all alterations. That said, this is still an optimization and/as it's less expensive to have a complex object on $scope than to have all of the similar fields as differing properties directly hanging off of $scope.

random things from a second dinner discussion

I guess this is the sequel blog posting for this.

  • An exploded view drawing is the formal name for those drawings where you see a mechanical device comprised of many parts in a manner in which the parts are separated apart and labeled.
  • Will artificial intelligence go anywhere? To date in a 1980s model it has had the shape of data analytics and "Expert Systems" wherein the later has to do with making the AI a SME (subject matter expert) that may be queried about a topic. NLP (natural language processing) is newer and allows for English (or other language) voice communications between people and machines and should also allow a translator to always be present when two human beings talk to each other in different tounges as a side effect bonus.