Monday, December 31, 2018

Did you know that you may put using declarations inside of a namespace in C#?

Now you know!

Toggl

There is yet another timesheet app at: toggl.com

How do the getsetters for a lazy loaded field get populated in Entity Framework 6's code first approach?

Well, instead of there being a getsetter there will be two fields like so:

private readonly Lazy<ICollection<Worker>> _workers;
public ICollection<Worker> Workers => _workers.Value;

 
 

When you stop at a breakpoint and inspect whatever has the Workers in Visual Studio 2017, you may, very likely, not see the Workers until you click on them (their variable title) there in the records list (coming off of you mousing over a variable in Visual Studio) to hydrate them.

migrations in Entity Framework 6

You need to run a command as follows at PowerShell and honestly I'd just run it at the NuGet command prompt inside Visual Studio:

EntityFramework\Add-Migration "AddReportOrderAndSurveyOrderToProgramSurvey"
      -ConfigurationTypeName "MyConfiguration"

 
 

There probably is a way to spec which project in a Visual Studio solution this applies to. On the team I am currently on, we sort of hack around that by just setting the infrastructure project to be the startup project just for a moment. We also change the "Default project:" dropdown at the NuGet console. Another thing you'll need is some sort of change to one of Entity Framework's code first files. In my case I added two nullable int getsetters to the ProgramSurvey POCO and the migration made a file called 201812311747128_AddReportOrderAndSurveyOrderToProgramSurvey.cs in the "Migrations" folder in the infrastructure project. This file also had companion Designer.cs and .resx files, but the .cs file itself looked like so:

namespace Something.Business.Migrations
{
   using System;
   using System.Data.Entity.Migrations;
   
   public partial class AddReportOrderAndSurveyOrderToProgramSurvey : DbMigration
   {
      public override void Up()
      {
         AddColumn("dbo.ProgramSurveys", "ReportOrder", c => c.Int());
         AddColumn("dbo.ProgramSurveys", "SurveyOrder", c => c.Int());
      }
      
      public override void Down()
      {
         DropColumn("dbo.ProgramSurveys", "SurveyOrder");
         DropColumn("dbo.ProgramSurveys", "ReportOrder");
      }
   }
}

 
 

By the way, if you every screw up one of these migrations and you decide that you just want to revert code and drop and recreate the database, you will find that Entity Framework can still get lost somehow. You may end up with a second migration that tries to address something you just threw away. I got around as much by closing Visual Studio 2017, deleting what was in the bin folder from the infrastructure project, opening Visual Studio anew, rebuilding the solution, and then starting to set everything else up from the beginning.

I had a coworker struggle with MVC's required attribute today.

[Required(ErrorMessage = "Acknowledgement of the Privacy Policy is required")]

 
 

...would show the default "The Name field is required" instead of "Acknowledgement of the Privacy Policy is required" and in attempting to help I looked at this and this and was ultimately no help. We tried jamming...

data-valmsg-replace="false"

 
 

...inline in the label to no avail. This just made neither error message show up. As this was for a checkbox we also tried:

[BooleanMustBeTrue(ErrorMessage="Acknowledgement of the Privacy Policy is
      required")]

 
 

...but no dice. Eventually, my coworker told me the inline solution was:

data-rule-required="true" data-msg-required="message"

Roll out a deployment at visualstudio.com!

  1. At the left nav, go to "Releases" under the "Pipelines" menu.
  2. To the right of the left navigation pane there will be a list of pipelines. Pick your pipeline.
  3. Click "Create a release" at the top right to roll out a deployment.
  4. There will be a little form to fill out but you can probably leave all of the fields blank.

Delete a comment/message from Slack!

Click on the three dots in a horizontal row that you see when you hover over the message (should be your own comment and not someone else's) with your mouse. This opens up a little menu with a delete option in it.

Sunday, December 30, 2018

Authenticate once against YouTube at your iPhone and you are always authenticated.

There is a security hole in the way the iPhone interacts with YouTube. It has been there since at least the iPhone4S. If you upload one movie to YouTube you will always be able to push up movies to that account, even after you change your password at Google. Just now I was able to push up this:

To see the ghetto phenomenon for yourself, just make a movie on your iPhone and then go into the settings for the video clip at your photos. The canned YouTube app from the early versions of the iPhone has long been removed but the canned push-to-YouTube option at your photos yet lingers... and it is sick.

https://m.youtube.com/watch?v=LAQlbqVIllQ was pretty easy for me to make even after I had changed my password. I guess Google and Apple are not infallible. I remember Paul Hammant calling me on a Sunday and blowing up at me because he let this fact slip out of his mouth at this tech talk when he maybe wasn't supposed to and I in turn blogged of it. Funny!

 
 

Addendum 12/8/2019: This is no longer the reality! This hole has been plugged!

Avid Studio has become Pinnacle Studio it seems.

This is another video editing tool like Adobe Premiere. dpsVelocity was another player in this space. It interfaces with DDR (Digital Disk Recorder) tech and DPS stands for Digital Processing Systems Inc.

I have finished chapter 5 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis.

It is going to be my New Year's resolution to finish this book by the end of 2019. I am now halfway done. I bought the book in hopes of learning more about Entity Framework and Angularland authentication and there really hasn't been too much of that yet. I have flipped ahead and it is coming. I have become burned out on this book and I while I had been reading a page a day and typing some code in some of the exercises involved, I have fallen out of that habit and have instead read the most recent twenty-eight pages quickly to get to the halfway point before year's end. I am through two hundred sixty-three of five hundred seventeen pages and five of ten chapters. What was "new" in the most recent twenty-eight pages? Nothing. The content was mostly on making boilerplate Angular code with a hint of the introduce middleman base controller stuff on the C# side. What was a little different? Five things:

  1. Methods that a component template reaches out to inside of a component, perhaps when a user clicks a button or so, are referred to as delegate methods.
  2. Did you know that you may treat the snapshot URL off of an ActivatedRoute instance as an array like so?
    if (this.activatedRoute.snapshot.url[0]) {
       console.log("zero");
       console.log(this.activatedRoute.snapshot.url[0]);
       console.log(this.activatedRoute.snapshot.url[0].path);
    }
    if (this.activatedRoute.snapshot.url[1]) {
       console.log("one");
       console.log(this.activatedRoute.snapshot.url[1]);
       console.log(this.activatedRoute.snapshot.url[1].path);
    }

    I looked at my own blog and it looks like I touch on this trick here, in my this.whereAreWeReally example that I do not do anything with, but that doesn't really explain the trick and I did not even remember writing about it. The trick is that we will fish out the slash divided chunks of the URL so if http://www.example.com/yin/yang/ were our URL this.activatedRoute.snapshot.url[0].path gets us "yin" and this.activatedRoute.snapshot.url[1].path gives us "yang" in contrast.
  3. I know I have other SimpleChanges examples on this blog, but here is yet another in which we go-a-fishing for something in particular with the bracket notation instead of the dot notation or looping through all of the properties.
    ngOnChanges(changes: SimpleChanges) {
       if (changes['somethingToFishFor']) {
          console.log(changes['somethingToFishFor']);
       }
    }


    This should again allow you to taste what has changed (at a variable for an Input coming into the component from a wrapping component) and assess the situation.
  4. An example of two-way databinding to a select list that kinda looks like so is given.
    <select id="lives" name="lives" [(ngModel)]="cat.NumberOfLives">
       <option *ngFor="let num of [0,1,2,3,4,5,6,7,8,9]" [value]="numby">
          {{numby}}
       </option>
    </select>
  5. A number input type field in HTML might be a good forum for a nullable number type in TypeScript to match up to as a user may either give a number or leave it blank.

Saturday, December 29, 2018

Zero State

I was thinking today of a client site I was almost deployed to and one of their in-house terms, zero state. Zero state is what you have when you have a list of records and there are zero records. You may want to accommodate for this off-the-happy-path scenario as part of the workflow of a story. A little list of similar concerns are:

  1. Zero state
  2. Copy for messages
  3. "Are you sure?" for deletes
  4. What if there is an error?
  5. What if the user doesn't have permissions?
  6. What if there is a concurrency issue?
  7. Does the feature need to be wrapped in an on/off switch for ease of empowerment and abandonment in various environments?
  8. Does the story title make sense?
  9. Do any new stories come to mind in addressing these questions?

An older concern you don't hear that much about anymore is... what if you double-click a button when submitting a record or refresh the page after submitting a record? Will you make a double entry? I guess this is still worth worrying about.

Friday, December 28, 2018

SPF records evolved out of .txt records in DNS and really just are .txt records.

A .txt record associates some human readable text to a domain name in DNS. The SPF records are just .txt records in a specific shape that SPF tools know how to sniff for and utilize. Why would you have a .txt record that is not an SPF record? Maybe you want to write a note to the world about what your domain name is all about.

You don't have to have multiple INSERT statements to insert multiple rows in T-SQL.

You may just chase what is in the last set of parentheses after VALUE with another set of parenthesis and then a third set after that and so on. Separate the sets of parentheses with commas like so:

DECLARE @MyStupidNumbers TABLE
(
   Numby INT
)
INSERT INTO @MyStupidNumbers (Numby) VALUES (13), (42), (69), (86)

Sender Policy Framework might be what SPF stands for.

I was orginally told "Server Protected From" but I thought of that just now and it seemed suspicious. See also:

I guess A for address and MX for Mail Exchanger. A CName in DNS points a domain name (subdomain) to another domain name (subdomain). C for canonical. TTL is time to live and is a setting for how long an A record, MX record, etc. may be cached. DNS may stand for Domain Name System instead of Domain Name Services.

Thursday, December 27, 2018

Can't find the autodiscover XML file?

Do you see failed web traffic to http://www.example.com/autodiscover/autodiscover.xml in your logs? The autodiscover.xml file is kinda like the WSDL of your Microsoft Exchange Server, but if DNS is messed up and your MX record just points to your web site or something then you may see your web site bombarded with failed requests to autodiscover.xml. Lame.

Moto Z

It is a Motorola Andriod smartphone. It has a "Moto Mods" case system in which the cases for the device can make the device do something extra such as a case that boosts the sound, etc.

ternary expressions in Razor markup

@if(!String.IsNullOrWhiteSpace(Model.Foo)) { @Model.Foo<text>...</text> }

 
 

Could be rewritten as...

@(!String.IsNullOrWhiteSpace(Model.Foo) ? Model.Foo + "..." : "")

Wednesday, December 26, 2018

CREATE OR ALTER PROCEDURE

Alright, this is a thing in T-SQL as of SQL Server 2016's 1st service pack. w00t! No more jumping through hoops to make this magic happen. Baller!

interactive rebasing

This is like rebasing in git only... yes, interactive! You may tweak the various commits along the way with edit, delete, and squash acrobatics.

Edge cascading autoguessing

It is kinda awful. I am used to browsers allowing me to start typing something that I have already typed in a form field and then allowing for the autocompletion of that field, but recently I am seeing scenarios in which I can start typing an address and then fill in all of the address fields with an autocomplete. Tacky.

Add a task to a product backlog item at visualstudio.com!

Drill into the splash page for the item, bearing its details, and click "Add link" under "Related Work" at the upper right. This assumes the "Details" tab is selected.

One of the girls at the Olive Garden was telling me that she got a Nintendo Switch for Christmas today.

I asked if that was the new platform after the Nintendo Wii and she said it was kinda like a hodgepodge of the Wii and a Nintendo DS. She said that it was like a tablet you could goof off with standalone or you could put it up on the TV screen. I had to ask about the Nintendo DS (I guess DS stands for dual-screen) and the DS seems to be something like a Game Boy handheld Nintendo device of yore. The Kanex GoPlay Sidekick is another comparable handheld thingy but not one from Nintendo. I think maybe you use your iPhone in tandem with the Sidekick like the Sidekick just bolts on some extra controls. I dunno. Stop playing games everyone. Learn to write code. While we are at this I thought of Second Life. It was sort of like an MMO only there was not a game really. You just wandered around in a funny 3D world and talked to people I think. EverQuest was the first really crack-addictive MMO.

Tuesday, December 25, 2018

Make regular expression patterns without wrapping double quotes in JavaScript!

function IsRegexMatchForName(subject) {
   let regExPattern = /^([A-Za-z\.'-]+[\s]*)+$/;
   let isMatch = !!subject.match(regExPattern);
   return isMatch;
}

 
 

...is more or less akin to...

function IsRegexMatchForName(subject) {
   let regExPattern = "^([A-Za-z\\.'-]+[\\s]*)+$";
   let isMatch = !!subject.match(regExPattern);
   return isMatch;
}

 
 

Note that there are some tiny differences between the RegEx of JavaScript and that of C#. This touches on them some. Note that the quoteless trick in JavaScript is kinda like the at symbol trick in C#! Some C#:

string foo = @"^([A-Za-z\.'-]+[\s]*)+$";

 
 

In both cases we are getting out of having to lead a backslash with a backslash.

Superclass and Subclass in Java

Page 234 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis has a sentence that ends with "in Java, a Base class is called Superclass, while the derived classes are known as Subclasses." which taught me something I didn't know about Java.

Monday, December 24, 2018

Set the state of a checkbox with boilerplate code in an Angular 6 application.

Assuming something like this...

@ViewChild('checky') checky: ElementRef<HTMLInputElement>;

 
 

You could have something like this:

if (this.modalMetadata.president.HasNonconsecutiveTerms) {
   this.checky.nativeElement.checked = true;
} else {
   this.checky.nativeElement.checked = false;
}

Sunday, December 23, 2018

the code HTML tag

You see it all over Stack Overflow, wrapping copy and doing stuff like this:

var scream = function(){
alert("Aaahhhhh!!!");
};

 
 

What is above is:

<code><pre>var scream = function(){<br />
(four spaces go here)alert("Aaahhhhh!!!");<br />
};</pre></code>

 
 

Should I have been doing what everyone else does this entire time on my blog?

Saturday, December 22, 2018

Make users for an Azure Active Directory B2C tenant.

Where it says Applications, Identity providers, User attributes, Users, Audit logs, User flows (policies), and Identity Experience Framework as a submenu, click "Users" to make users. I was encouraged to make a user that had the same onmircosoft.com subdomain so I made one with tom@tomoutlook.onmicrosoft.com as the email address. Once an account is made, you may click on it at its list and see an Azure Object ID in the specs for it. There will be a link here for "Reset password" to to make an initial password (not part of the creation process).

navigating in and out of an Azure Active Directory B2C tenant from the wrapping account

If you click the "Directory + Subscription" icon which looks a funnel laid on a book and sits to the right of the Cloud Shell icon (a greater than symbol followed by an underscore) to the right of the search bar you may toggle between the two. If you are in Azure AD B2C and you do not see Applications, Identity providers, User attributes, Users, Audit logs, User flows (policies), and Identity Experience Framework as a submenu, you may get there by punching in "Azure AD B2C" at the serach bar.

When you commit to your branch and you already have a pull request in for the branch at visualstudio.com and you are just making corrections...

The pull request will update by itself upon your commit. You don't need to do anything extra.

Friday, December 21, 2018

Change where a pull request is being merged to at visualstudio.com!

Below the name of the pull request, when you are looking at it, it will say A into B wherein A and B are blue links and I do not literally mean A and B but I mean your branch and where you are gonna stick it. If you mouse over the B link a pencil appears by it and you may click on the pencil to edit.

The kernel of an operating system is the central authority.

the body of the octopus controlling the tentacles

I thought of URL shortening services in the night.

I guess there is an example of bit.ly here. For the most part I don't like using these. It's bad for SEO and another thing that can go wrong. Also the terse URLs are hard to read. I haven't heard about this stuff in a long while. I guess it was trendy back in 2012.

Thursday, December 20, 2018

Add user flow policies at a B2C tenant at the Azure Portal.

  1. Go into your tenant. You may be able to find it at your resource.
  2. Down the left side you will see options for Applications, Identity providers, User attributes, Users, Audit logs, User flows (policies), and Identity Experience Framework
  3. Click "User flows (policies) to create policies for Profile editing, Password reset, and Sign up and sign in

Merge into current branch... Ctrl+Shift+M

This is one of the options in the "Branch" dropdown in the top menu at the Window's Desktop Client for GitHub. It does exactly what you think it does. Pull master into your branch before making a pull request, etc.

Make pull requests at visualstudio.com!

Go to yourthing.visualstudio.com and then go to "Pull Requests" under the "Repos" accordion at the left.

Wednesday, December 19, 2018

NSK TACL

TACL is the Tandem Advanced Command Language of Tandem Computers, now a part of HP (Hewlett Packard). NonStop Kernel or NSK is an operating system that was made in TACL.

Create an App Registration at the Azure portal

  1. Go to https://portal.azure.com/ and search at the top center search bar for: "App registrations"
  2. Create an application here. You will need a Sign-on URL. Something like: https://localhost:44396/
  3. Search for "App registrations" again.
  4. You will need to click the "View all applications" button to see the thing you just made as a line item in the otherwise empty list.
  5. Find the thing you just made, click on it to select it, and then click the "Settings" gear at the upper right.
  6. Click "Required permissions" and then "Grant permissions" to add permissions such as "Read and write directory data" or click Keys to add secret keys.

 
 

Addendum 12/21/2018: You will need to click "Windows Azure Active Directory" to set permissions (and I recommend adding "Read and write directory data") before clicking the "Grant permissions" button to make the changes stick.

ES6 data hydration stuff

To run the migrations for Entity Framework version 6, which are really just a bunch of sequential scripts kept in the dbo.__MigrationHistory folder and not rerun if recorded there (sounds like AliaSQL, eh?) go into the NuGet Package Manager Console in Visual Studio 2017. At the "Default project:" dropdown pick the infrastructure project which is probably not your UI project and also right click on your infrastructure project in Solution Explorer and pick "Set as StartUp Project" and finally run this:

EntityFramework\Update-Database -ConfigurationTypeName "MyConfiguration"

RenderSection can only be called from a layout page.

Don't try to set a section in a partial from the thing wrapping it in Razor. You'll get this error.

How do I hand a partial into a partial from a Razor view wrapping the second partial?

You could make a div in the partial and inject stuff into it like so:

<script type="text/javascript">
   $(document).ready(function () {
      $.ajax({
         type: "GET",
         url: "/Yin/Yang",
         dataType: 'html',
         success: function (result) {
            $("#nestedGunk").html(result);
         },
         error: function (error) {
            console.log("error in reaching out to /Yin/Yang");
            console.log(error);
         }
      });
   });
</script>

 
 

If you want to do a post instead of a get and hand over the model, you can get at the model like this:

var json = @Html.Raw(Json.Serialize(@Model));

Connect-MsolService is deprecated.

I have run "Install-Module MSOnline" at PowerShell and then, following that, I have run the "Connect-MsolService" command. When I attempt to give credentials for my Azure account which is tied to tom.jaeschke@outlook.com I am told: "This doesn't look like a work or school email. You can't sign in here with a personal account. Use your work or school account instead." I had to get on the phone with Microsoft and in the end I was told to use this command instead:

login-azureRMAccount

RequireIfValue in .NET Core MVC

If you have a getsetter like this in your model:

[RequireIfValue(nameof(FooId), 13, ErrorMessage = "You must select a bar id!")]
[Display(Name = "Bar Id")]
public int? BarId { get; set; }

 
 

Then if you fill out a form in Razor and you set FooId to 13 and you do not set the BarId you will get this error here in the Razor markup:

<span asp-validation-for="@Model.BarId" class="text-danger"></span>

 
 

Addendum 1/10/2019: @Html.LabelFor(model => model.BarId) is an example of what the Display attribute wires up to.

AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis, a book by William J. Brown

I remember John Heintz piping up about this a few times during the Jay-Sea-Em-Es project. The "big ball of mud" is an antipattern where there is no real architecture and anything goes and the "lava flow" is antipattern in which things are easy to change at first, but then the lava cools to rock and it gets harder and harder to make changes.

Tuesday, December 18, 2018

Google Geolocation API Key

Follow this link and get an API Key. Then turn on the API for the key like so:

  1. Click Libary at the left nav
  2. Go to "Maps JavaScript API"
  3. Click "Enable"

my.visualstudio.com

You may activate a $150 monthly credit for an Azure account here. There will be an "Azure" box with an "Activate" button in it.

Where do I check my outlook.com email address?

At https://outlook.live.com ...note that when you first attempt to send mail from the webmail that the email will get hung up as a draft and you have to go back into the mail and click a link to verify that you are not a robot and do some CAPTCHA stuff.

The Surface Book and Surface Pro 6 are high-end PCs.

These kinda compete with the Macbook Pro Apple laptops in terms of being way posh snob fetish fodder and not just junker Dell machines. Remember when DEC Alpha used to be all that? DEC stood for Digital Equipment Corporation.

Tailwind CSS

This is a bootstrap rival. It is some sort of overarching infrastructure for your CSS.

 
 

Addendum 1/17/2019: Supposedly, this is "functional" CSS. You jam a lot of little styles inline in a class parameter at an HTML tag. There will be one class for five pixels of padding and another for making the text bright red, etc. The names of these classes are all really terse like their scopes and this allows for readability at the HTML in lieu of a need to crack back open the .css file to figure out what is going on.

How do I transfer a Visual Studio Subscription from one Azure account to another?

It's not easy.

  1. Make a 2nd account at https://azure.microsoft.com/en-us/offers/ms-azr-0003p/ verifying your phone number and entering credit card information.
  2. Go into the account you wish to transfer from at https://my.visualstudio.com and then click "Subscriptions" at the top nav. Finally click the "Add alternate account" link to associate the new account.
  3. Microsoft is going to have to do the transfer for you if you don't see a "Change sign-in" link like I didn't. Call them at 1 (800) 642-7676.

Link an existing Azure AD B2C Tenant to my Azure subscription.

  1. Search for Azure Active Directory B2C at the top searchbar at https://portal.azure.com/
  2. Pick: "Link an existing Azure AD B2C Tenant to my Azure subscription"
  3. A little form will appear that allows you to associate the tenant with a resource.
  4. You may then just go to your resource to have a link into the tenant.

 
 

When this is done you may click on the "Click the Azure AD B2C Settings" tile to drill into the tenant and once inside click on "Applications" at the left to make an application for the tenant. Clicking on "User flows (policies) will similarly allow you to create a sign up/sign in policy, profile editing policy, and password reset policy. If you drill into an application you made there will be a "Keys" link at the upper left that you may use to make a secret key for the application.

A mod in a game is a modification.

I had thought that mods were meshes, 3D (three-dimensional) objects in 3D (three-dimensional) games, but a mod doesn’t necessarily have to be a third party mesh.

Papercut

This is yet another dummy SMTP server for testing an application's email stuff when developing locally. This one is in .NET and the code is a solution.

join.me

This is yet another WebExesque tool. GoToMeeting has many rivals.

Azure Active Directory B2C tenant

Click "Create a resource" at the right at https://portal.azure.com/ and then search for "B2C" to make a tenant. I gave TomJaeschkeOrg for organization name and tomjaeschke.onmicrosoft.com for the initial domain name.

database settings at Azure "Resource groups"

Go to a Resource Group at https://portal.azure.com and at a database server click "Show firewall settings" to allow your own IP address to see the databases at that server. At the individual databases click Basic at Pricing tier to pick a setting other than Basic and click Connection strings to actually get a connection string for the database.

planar/Euclidean/flat-earth and geography/ellipsoidal/round-earth are the two kinds of spatial data types

This has some notes on the them which I do not yet understand and this has an installer. This is T-SQL stuff.

Set Credentials

When you click the link for cloning a repository at yournamehere.visualstudio.com you will see an option for "Set Credentials" that will allow you to create a login and password so that you may clone the repo in at GitHub's desktop client. Note that when it comes down, you get the master and not the branch you were looking at back at visualstudio.com and you will have to change branches inside of the desktop app.

Azure subscriptions, resource groups, and deployments

At https://portal.azure.com just type "subscriptions" in the search bar to see a list of the subscriptions and their subscription Ids. There is a menu item for "Resource Groups" at the left and beneath a particular resource group you may see the deployments.

Navigate to a folder that has a space in it in PowerShell by enclosing the path in double quotes.

set-location "C:\This thing"

 
 

...or, if you're like me and you never really let go of DOS, you can do this:

cd "C:\This thing"

Manage User Secrets

Right-click on your UI project in Visual Studio 2017 when working with .NET Core and pick "Manage User Secrets" to create a secrets.json file which in many ways in kinda like Web.config.

Monday, December 17, 2018

HideTrustIISCertificatePrompt?

I have seen some things online that suggest that you have to put in a registry key like so:

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0\WebProjects]
"HideTrustIISCertificatePrompt"=dword:00000001

 
 

...to get out of repeatedly seeing this in Visual Studio:

This project is configured to use SSL. To avoid SSL warnings in the browser you can choose to trust the self-signed certificate that IIS Express has generated. Would you like to trust the IIS Express SSL certificate?

 
 

I only got the prompt once myself. I agreed in Visual Studio 2017 to set up some substitute certificate and that was enough.

PowerShell execution policies

MachinePolicy, UserPolicy, Process, CurrentUser, and LocalMachine are examples of scopes and each of these may have a setting such as Undefined, Unrestricted, Bypass, or AllSigned. This has an example of setting the setting for Process to Bypass. It's possible to get errors like this with this stuff:

Windows PowerShell updated your execution policy successfully, but the setting is overridden by a policy defined at a more specific scope. Due to the override, your shell will retain its current effective execution policy of Bypass. Type "Get-ExecutionPolicy -List" to view your execution policy settings. For more information please see "Get-Help Set-ExecutionPolicy".

 
 

An example of setting the execution policy for a particular scope is:

Set-ExecutionPolicy Unrestricted -Scope CurrentUser

Something went wrong with your payment method, and your tip can't be added.

You probably changed credit cards and Uber let you get away with making a trip only to throw a fit when you tried to tip. I ran into this today. When you next take a ride, you will have to reenter your credit card data and then you may go back into your history and find the prior driver and tip them.

Sunday, December 16, 2018

infotainment

This was a very 1990s term for a subset of multimedia CD-ROM presentations to both entertain and inform, stuff that was to be used by kids in schools.

How do I turn back off the read only state on an HTMLFormElement in an Angular 6 application?

Assuming...

@ViewChild('opener') opener: ElementRef<HTMLFormElement>;

 
 

...and assuming...

this.opener.nativeElement.readOnly = "true";

 
 

You may turn back off the read only thing like this.

this.opener.nativeElement.readOnly = "";

 
 

This however will not work.

this.opener.nativeElement.readOnly = "false";

headless server

This is a machine deferred to by other machines for computing power that human beings do not directly interface with.

Saturday, December 15, 2018

I've done some work this past week with what I suspect to be the jQuery UI dialog.

See: this $("myThing").dialog("close"); closes it and $("#myThing").dialog("open"); opens it.

Reddit's chat feature is consistently broken.

What gives guys? At https://www.reddit.com/ click the two cartoon word bubbles together at the upper left. It brings up a window that does nothing.

 
 

Addendum 12/16/2018: upper right NOT upper left

Progressive call an API sequentially with an ordering defined by the items in an array with jQuery.

var addAddresses = function (addresses) {
   if (addresses.length == 0) {
      alert("All done!");
      return false;
   }
   var address = addresses.shift();
   $.ajax({
      type: "POST",
      url: "/AddressValidation",
      data: address,
      success: function(response) {
         $("#AddressValidationFormWrapper").append(response);
         AddAddresses(addresses);
      },
      error: function () {
         alert("Yikes!");
         AddAddresses(addresses);
      }
   });
};

Use .each in jQuery without chaining it onto something.

Beyond this you can do stuff like this:

$.each(things, function (index, value) {
   alert("position " + index + " has: " + value);
});

 
 

Note that the first variable coming back from the each is an index and the second is the actual item in the collection. This messed with my mind some. Here is an example of the chaining:

$(".stuff").find("button").each(function (outerIndex, outerValue) {
   $(outerValue).children().each(function (innerIndex, innerValue) {
      if ($(innerValue).html() === "Bulk Paste") {
         $(outerValue).attr('style', "display: none;");
      }
   });
});

 
 

The parenthesis with leading dollar sign must wrap innerValue to do a .html() off of it. If you are struggling with getting jQuery methods to work, make sure you are not missing this piece.

How do I see my Google Calendar?

Log in as you and then go to: https://calendar.google.com/

Thin Clients

A thin client is an otherwise regular PC that has no hard drive. It just uses a server on the LAN for its storage needs.

Thursday, December 13, 2018

.first() in jQuery

When there is more than one thing to match on, filter down to the first match like so:

$("#BulkUpload").find('button').first().attr('style', "display: none;");

You may post a "nested" object to an MVC endpoint to hydrate both simple variables and POCOs therein.

Assuming an ASP.NET MVC endpoint like so:

[HttpPost]
public ActionResult SaveEditedAddress(int foo, Bar baz, string qux)
{

 
 

Hand it a JSON object like so:

var postPacket = {
   foo: 13,
   baz: {
      yin: 42,
      yang: 69
   },
   qux: "eighty-six"
};

See if a checkbox is checked by way of its id in jQuery.

var isChecked = $("#Foo").is(":checked");

.length in jQuery should get you a count of a query.

var quantity = $("div").length;

the land before Razor

Do you kids remember this view syntax from the first two versions of ASP.NET MVC before Razor showed up?

<% if (!String.IsNullOrEmpty(Model.PurchaseOrder))
   { %>
<div class="po">
   <p>PO #: <%= Model.PurchaseOrder %></p>
</div>
<% } %>

 
 

The model binding at the top of a view looked like this:

<%@ Page Title="" Language="C#"
      MasterPageFile="~/Views/Shared/OrderMaster.Master"
      Inherits="System.Web.Mvc.ViewPage<SomethingErOther.Models.Order>" %>

 
 

Loop in a partial like so:

<% Html.RenderAction("Index", "Foo", Model.Bar); %>

Wednesday, December 12, 2018

Leave site? Changes you made may not be saved.

I see this at Reddit when I try to bail on changes in Google Chrome. Wrangling the WindowEventHandlers.onbeforeunload in JavaScript seems to be the way to approach making something like this possible. How else can a web site know that you are clicking on bookmark and trying to abandon ship? See:

You may query in jQuery for something with more than one class on it!

$(".foo, .bar, .baz, .qux").find('button').attr('style', "display: none;");

 
 

(.find will find something within the element you match upon above.)

Homebrew and Nix

I saw Sukant Hajra tweet of how he has started working with MacOS for the first time last night. I'm about to be in the same situation. He mentioned Homebrew and Nix. These are package management tools. People install open-source software with these.

'Foo' is a type, which is not valid in the given context.

I was getting this error at a model binding in a .cshtml view in the Razor markup. After I just ran the application and navigated to the point of pain however the error message disappeared.

.live is not a function

.live in jQuery is no more. Use .on from now on. So this...

$("#goBack").live('click', function() {

 
 

...has to become this:

$("#goBackWrapper").on('click', '#goBack', function() {

 
 

You have to reference the element inside of the element you wish to affect with the live effect now and that really sucks! :(

Use Razor for other templates in C#, not just Controller views.

They can be used for email templates and the like. In the code below I use a .cshtml view full of Razor to prep the XML for this API, though be warned the code below only supports the happy pass scenario.

using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using SomethingErOther.Core;
using RazorEngine.Templating;
namespace SomethingErOther.DataAccess
{
   public class AddressValidationRepository
   {
      public AddressValidationAPIModel UseService(string street1, string street2, string
            city, string state, string zip, string url, string username)
      {
         TemplateService templateService = new TemplateService();
         AddressValidationXMLModel addressValidationXMLModel = new
               AddressValidationXMLModel(street1, street2, city, state, zip, username);
         string xml = GenerateProgramEmailBody(templateService,
               addressValidationXMLModel);
         return CallApi(String.Format("{0}?API=Verify&XML={1}", url, xml));
      }
      
      private string GenerateProgramEmailBody(TemplateService templateService,
            AddressValidationXMLModel addressValidationXMLModel)
      {
         var template = LoadEmbeddedTemplate();
         return templateService.Parse(template, addressValidationXMLModel, null, "XML");
      }
      
      private string LoadEmbeddedTemplate()
      {
         var assembly = Assembly.GetExecutingAssembly();
         using (var stream = assembly.GetManifestResourceStream(
               "SomethingErOther.DataAccess.AddressValidationTemplates.XML.cshtml"))
         {
            using (var reader = new StreamReader(stream))
            {
               return reader.ReadToEnd();
            }
         }
      }
      
      private AddressValidationAPIModel CallApi(string url)
      {
         using (WebClient webClient = new WebClient())
         {
            byte[] bytes = webClient.DownloadData(url);
            string result = Encoding.UTF8.GetString(bytes);
            return ParseXML(result);
         }
      }
      
      private AddressValidationAPIModel ParseXML(string xml)
      {
         AddressValidationAPIModel addressValidationAPIModel = new
               AddressValidationAPIModel();
         XDocument xmlDocument = XDocument.Parse(xml);
         foreach (XElement outerElement in xmlDocument.Root.Elements())
         {
            foreach (XElement innerElement in outerElement.Elements())
            {
               switch (innerElement.Name.ToString())
               {
                  case "Address1":
                     addressValidationAPIModel.Street2 = innerElement.Value;
                     break;
                  case "Address2":
                     addressValidationAPIModel.Street1 = innerElement.Value;
                     break;
                  case "City":
                     addressValidationAPIModel.City = innerElement.Value;
                     break;
                  case "State":
                     addressValidationAPIModel.State = innerElement.Value;
                     break;
                  case "Zip5":
                     addressValidationAPIModel.Zip = innerElement.Value;
                     break;
                  case "Zip4":
                     addressValidationAPIModel.Zip = String.Format("{0}-{1}",
                           addressValidationAPIModel.Zip, innerElement.Value);
                     break;
                  default:
                     break;
               }
            }
         }
         return addressValidationAPIModel;
      }
   }
}

Get the value of the checked radio button in jQuery.

var whichWayToGo = $("input[name=Address1]:checked").val();
if (whichWayToGo === "New") {

Tuesday, December 11, 2018

The good-enough-for-government-work USPS API offers SOAP messaging without a WSDL.

The United States Postal Service has an API for trying to suggest a better street address for a given address in the name of trying to not screw up orders in the mail. You have to register here and then you will be given a username and a password. I do not know what you might do with the password, but you may use the username like so:

https://secure.shippingapis.com/ShippingAPI.dll?API=Verify&XML=
<AddressValidateRequest USERID="LETMEIN">
   <Revision>1</Revision>
   <Address ID="0">
      <Address1>8080 Eden Road</Address1>
      <Address2></Address2>
      <City>Eden Prairie</City>
      <State>MN</State>
      <Zip5>55344</Zip5>
      <Zip4></Zip4>
   </Address>
</AddressValidateRequest>

 
 

What is above may just be copied and pasted into the URL line of a browser to make this stuff work. (Well, LETMEIN needs to be swapped out with a better username.) You make GET calls and instead of passing URL line variables in the usual way you pass a bunch of XML. I am serious. This and this has some more about it. What is above returns the following because I left off my apartment number.

<?xml version="1.0" encoding="ISO-8859-1"?>
<AddressValidateResponse>
   <Address ID="0">
      <Address2>8080 EDEN RD</Address2>
      <City>EDEN PRAIRIE</City>
      <State>MN</State>
      <Zip5>55344</Zip5>
      <Zip4>5309</Zip4>
      <DeliveryPoint>99</DeliveryPoint>
      <ReturnText>Default address: The address you entered was found but more
            information is needed (such as an apartment, suite, or box number) to match to a
            specific address.</ReturnText>
      <CarrierRoute>C002</CarrierRoute>
      <Footnotes>HN</Footnotes>
      <DPVConfirmation>D</DPVConfirmation>
      <DPVCMRA>N</DPVCMRA>
      <DPVFootnotes>AAN1</DPVFootnotes>
      <Business>N</Business>
      <CentralDeliveryPoint>N</CentralDeliveryPoint>
      <Vacant>N</Vacant>
   </Address>
</AddressValidateResponse>

 
 

I think you may lead in with http://production.shippingapis.com/ instead of https://secure.shippingapis.com/ but I don't know why you would. If I put in my apartment number like so...

https://secure.shippingapis.com/ShippingAPI.dll?API=Verify&XML=
<AddressValidateRequest USERID="LETMEIN">
   <Revision>1</Revision>
   <Address ID="0">
      <Address1>8080 Eden Road</Address1>
      <Address2>261</Address2>
      <City>Eden Prairie</City>
      <State>MN</State>
      <Zip5>55344</Zip5>
      <Zip4></Zip4>
   </Address>
</AddressValidateRequest>

 
 

...I get this instead:

<?xml version="1.0" encoding="ISO-8859-1"?>
<AddressValidateResponse>
   <Address ID="0">
      <Address1>APT 261</Address1>
      <Address2>8080 EDEN RD</Address2>
      <City>EDEN PRAIRIE</City>
      <State>MN</State>
      <Zip5>55344</Zip5>
      <Zip4>7604</Zip4>
      <DeliveryPoint>61</DeliveryPoint>
      <CarrierRoute>C002</CarrierRoute>
      <Footnotes>N</Footnotes>
      <DPVConfirmation>Y</DPVConfirmation>
      <DPVCMRA>N</DPVCMRA>
      <DPVFootnotes>AABB</DPVFootnotes>
      <Business>N</Business>
      <CentralDeliveryPoint>Y</CentralDeliveryPoint>
      <Vacant>N</Vacant>
   </Address>
</AddressValidateResponse>

 
 

When I make the very human mistake of leading my apartment number with a pound sign...

https://secure.shippingapis.com/ShippingAPI.dll?API=Verify&XML=
<AddressValidateRequest USERID="LETMEIN">
   <Revision>1</Revision>
   <Address ID="0">
      <Address1>8080 Eden Road</Address1>
      <Address2>#261</Address2>
      <City>Eden Prairie</City>
      <State>MN</State>
      <Zip5>55344</Zip5>
      <Zip4></Zip4>
   </Address>
</AddressValidateRequest>

 
 

Look at this!

<?xml version="1.0" encoding="ISO-8859-1"?>
<Error>
   <Number>80040B19</Number>
   <Description>XML Syntax Error: Please check the XML request to see if it can be
         parsed.(B)</Description>
   <Source>USPSCOM::DoAuth</Source>
</Error>

How do I give a checkbox the readonly setting?

This suggests this which seems to work.

<input type="checkbox" onclick="return false;"/>

 
 

Addendum 12/15/2018: In Angular 2 and up...

<input type="checkbox" [disabled]="myBooleanVariableBackInTheComponent" />

Use an HTMLInputElement type ElementRef instead of an HTMLElement type ElementRef to get at the value of a form field or to set the readonly state in an Angular 7 application.

Following up on this, I offer this example:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { YinYang } from './yinyang.model';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   @ViewChild('yin') yin: ElementRef<HTMLInputElement>;
   @ViewChild('yang') yang: ElementRef<HTMLInputElement>;
   constructor() { }
   act(){
      if (this.yin.nativeElement.readOnly) {
         this.yin.nativeElement.readOnly = false;
         this.yang.nativeElement.readOnly = false;
      } else {
         let yinYang = new YinYang();
         yinYang.Yin = this.yin.nativeElement.value;
         yinYang.Yang = this.yang.nativeElement.value;
         this.yin.nativeElement.readOnly = true;
         this.yang.nativeElement.readOnly = true;
      }   
   }
}

Set up all of the boilerplate code for Redux with Angular 7.

Per this I ran the following command line commands against an Angular 7 app.

ng add @ngrx/store
ng add @ngrx/effects
npm install @ngrx/schematics --save-dev
npm install @ngrx/store @ngrx/effects @ngrx/store-devtools @ngrx/router-store --save
ng config cli.defaultCollection @ngrx/schematics
ng generate store State --root --statePath store/reducers --module app.module.ts
ng generate effect store/App --group --root --spec false --module app.module

 
 

After all that, the imports in app.module, the first-point-of-entry God module, both had some dupes and a path that was bad. I cleaned them up to this:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StoreModule } from '@ngrx/store';
import { reducers, metaReducers } from './reducers';
import { EffectsModule } from '@ngrx/effects';
import { AppEffects } from './app.effects';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { environment } from '../environments/environment';

 
 

Next, I installed the Redux plugin for Google Chrome Developer Tools from here and to my dismay I saw...

No store found. Make sure to follow the instructions.

 
 

...as an error there. Per this I ran the following command to fix that:

npm install @angular-redux/store@^9

How do I refresh the Angular CLI?

Well, I followed the advice here and that seemed to work alright. That advice was:

  1. npm uninstall -g angular-cli
  2. npm cache verify
  3. npm install -g @angular/cli@latest

Monday, December 10, 2018

[ts] Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. [1219]

This means setting javascript.implicitProjectConfig.experimentalDecorators to true at C:\Users\Thomas\AppData\Roaming\Code\User\settings.json or where else you may have this file at. At: File > Preferences > Settings ...click the three dots in a horizontal line at the upper left of Visual Studio Code 1.29.1 and pick "Open settings.json" to get at this.

Wikipedia's links and how the pipe symbol is used in their markup

At https://en.wikipedia.org/wiki/Vice_(2018_film) I noticed, in attempting an edit...

It is the second theatrical film to depict the [[George W. Bush]] administration, following [[Oliver Stone]]'s ''[[W. (film)|W.]]'', and is the fourth collaboration between Bale and Adams, following ''[[The Fighter]]'', ''[[American Hustle]]'' and ''[[The Big Short (film)|The Big Short]]''.

 
 

The links that appear on the page do not have the "(film)" in them and I think you can see how the pipe symbol is used to sidestep this.

Sunday, December 9, 2018

Wrong version of TypeScript for Angular 6?

Getting this?

ERROR in The Angular Compiler requires TypeScript >=2.7.2 and <2.8.0 but 3.1.4 was found instead.

 
 

Try this:

npm install typescript@2.7.2

ElementRef became a generic in Angular 6!

If you see this error in Visual Studio Code...

[ts] Generic type 'ElementRef<T, any>' requires 2 type arguement (s).

 
 

...and it seems like this won't fly...

@ViewChild('foo') foo: ElementRef;

 
 

...try this instead:

@ViewChild('foo') foo: ElementRef<HTMLElement, any>;

 
 

You will then be able to use it as you might expect.

this.foo.nativeElement.style.display = "none";

 
 

I write again. On second thought...

@ViewChild('foo') foo: ElementRef<HTMLElement>;

 
 

...is probably better. Visual Studio Code still acts like there is a problem, but the compiler compiles for TypeScript 2.7.2. while I cannot do so with the any jammed in there. Wait, I closed and reopened Visual Studio Code after...

npm install typescript@2.7.2

 
 

...and now Visual Studio Code is happy too. Wait. I spoke too soon. More later maybe.

 
 

Addendum 12/10/2018: To fix the Visual Studio Code problem just uninstall Visual Studio Code and then go get it from the web anew.

Saturday, December 8, 2018

Does Xamarin have your trust?

At the Twin Cities .NET User Group on Thursday night I saw three lightning talks. Adam Zucchi gave talk 2 of 3 on Xamarin Essentials. Alright, this had just been the pet GitHub project of a James Montemagno for some time, but now Microsoft has bought it and there has been an official version 1 release. You may get Xamarin Essentials as a NuGet package and then just reference it in a project within a Visual Studio solution (the NuGet package install will really do this for you) and finally, of course, include a namespace reference to it at wherever in your own code you may wish to use it. In other words the setup is easy and everything you'd expect as a .NET developer. Adam didn't break into goofy XML configurations or anything like that. So what does this do? It allows you to interact with some of the more esoteric trappings of a smartphone (as suggested in this IoT tech talk I saw in Orlando) such as the Accelerometer. Magnetometer/Compass? Flashlight? Gyroscope? Battery? Clipboard? Yes, yes, yes, yes, and yes. In looking back at a photo I took from my phone at one of Adam's slides I see "Barometer" on his list too. I had to Google against this for as to why I would care and I suppose that if one can measure atmospheric pressure that one can estimate altitude. In the first photo here a saleswoman named Jen Simon is shown standing while William Austin tries to iron out the kinks of her slideshow presentation. She gave a talk on sales in general and cornerstone to her presentation was emphasizes on building trust and being honest. Her talk was last and immediately following Adam's talk she piggybacked onto his topic and posed the question: "Does Xamarin have your trust?" I guess I trust it more now that I can access more than just the camera and maps/geolocation stuff from Xamarin. The notion that I could go off into the weeds with some of this wacky stuff that I'll probably never touch does make it seem posh instead of Mickey Mouse. The prohibitive negative for .NET peeps used to PCs is that you yet really need a Macintosh to work with it (per this). Mark Kalal gave the first of the three lightning talks. His talk was just on a bunch of silly products. The one I found the most interesting was a keyboard from Microsoft that could fold in half. You can see it here. I suppose this device that allowed one to either plug into the two prong European electric ports or the American states-side electrical socket was pretty neat as well. In this last picture, Mark is pictured at left, Adam in the center, and at right is Jason Erdahl of ILM Services who was the main host for the night. ILM itself of course is the venue which hosts the event.

G1M

I saw an act today, and yesterday some too, (it was a rock concert straddling the midnight when yesterday became today) called G1M perform songs from an album called "Lois Lane" and what is more this was the release party for the album. Anyhow the photo here of that Graham guy who bartends at the Olive Garden in Bloomington, Minnesota that I always eat at and I guess who uses the stage name G1M and the video as well were taken today specifically after the turn of midnight.

The Twin Cities are full of Somali immigrants displaced by the mess that "Black Hawk Down" movie was all about. "The Red Sea" is technically an Ethiopian dive not a Somali one, but along those lines it has the Somali vibe. 320 Cedar Ave, Minneapolis, Minnesota 55454 was the spot for this event, and, yes, the Somali/Ethiopian bar/restaurant is also, surreally, a music venue.

The show was better than I expected it to be. At the end of the night Graham brought his girlfriend who recently became his wife, Lauren, on stage and sang to her. It was fun.

 
 

Addendum 2/18/2019: Graham is a Mr. Graham Germo and Lauren a Lauren Olson.

Friday, December 7, 2018

killer keyof IntelliSense at TypeScript in Visual Studio Code

In Visual Studio Code I see a red squiggly line underneath doSomething here:

spyOn({}, 'doSomething');

 
 

This is because {} does not have a doSomething method, but how can the IntelliSense pick that up? Well, If I put my cursor on spyOn and press F12 to drill into it. I see this at \node_modules\@types\jasmine\index.d.ts:

declare function spyOn<T>(object: T, method: keyof T): jasmine.Spy;

 
 

The keyof is empowering this magic.

Just as you may turn an it into a fit in a Jasmine test to run just the fit tests...

...you may likewise turn describe into fdescribe. The f is for focus. Focus on this and ignore the other items.

noImplicitAny compiler option for TypeScript

Per this, there are many things that may go in the compilerOptions option at tsconfig.json, and noImplicitAny will throw errors at the compiler in a type is not declared in such a manner that TypeScript has to fall over to assuming a type of any. Explictly using any is OK, but the thing one is really trying to get away from here is "JavaScript in your TypeScript" in a not idiomatic way, even though TypeScript is a superset of JavaScript. That is, we are trying to make sure we are using types in TypeScript.

the other Jest

There is a testing platform called Jest, but this is alternatively REST for Java stuff.

The deps setting in inversion of control in Angular 7.

Imagine the first bit of code I have here for IoC at an Angular module:

providers: [
   Configuration,
   {provide: IpContract, useClass: IpService}
]

 
 

What if IpService itself needs some stuff handed into it to make it work? Well, we could have a variant of what is above like this:

providers: [
   Configuration,
   {provide: IpContract, useFactory: IpService, deps: [Yin, Yang]}
]

 
 

Here is a trick to moreover refer to references in this ilk which are declared but not yet defined. The details may be filled in later.

providers: [
   Configuration,
   {provide: IpContract, useFactory: IpService, deps: forwardRef(() => IpMagic)}
]

package-lock.json

This file is generated when an npm command alters package.json or the node_modules folder and it describes the exact tree in the node_modules folder without the caret and tilde wiggle room stuff.

Tree-Shakeable Tokens

This all has to do with dependency injection within Angular. I don't understand it all yet. It is a thing. This has a geek out on as much.

DataDog

It is yet another monitoring tool.

The as keyword at an import in TypeScript.

These two things can live side by side in happiness.

import { ScrollingModule } from '@angular/cdk/scrolling';
import { ScrollingModule as ExperimentalScrollingModule } from
      '@angular/cdk-experimental/scrolling';

Page Up and Page Down keys may be used to scroll a scrollbar at a web browser.

Nice.

Kibana for logging?

It's a thing! You may browse the log files with Kibana. Metadata is data about the data, y'all. Make your data taste good.

optional properties at constructor signatures in TypeScript

You may call this constructor with either one or two things. Get it?

constructor(foo:string, averager = new AverageSizeAverager()) {

 
 

The Optional decorator of Angular lets this happen too like so:

constructor(foo:string, @Optional() averager: AverageSizeAverager) {

 
 

Do note that these two things have two different states if the second variable goes unset.

trackBy in an *ngFor

Imagine...

<div *ngFor="let mouse of mice; let i=index; trackBy: myFunction">

 
 

...or even...

<div [ngForOf]="mice" let-i=index [ngForTrackBy]="myFunction">

 
 

Alright, the trackBy references a function in the component that will be used to assign a unique identifier to a given mouse instead of justing using the pointer for the mouse for as much. The problem with the pointer occurs in the Redux pattern wherein when you "save" something back to the store you actually destroy it and recreate it so as not to mutate state. If you are using the pointer as a key in an *ngFor list listening back to the store, the list could flicker or resort upon the shake up.

moduleId and providers metadata properties at a component in Angular 7

A component may have a providers metadata property just as a module might. It's the same thing. Having moduleId: module.id as a metadata property and it's assignment allows for easier relative paths to a template or a .css file per this. Also, I don't know if I've mentioned it at this blog or not but instead of a templateUrl metadata property you may have a template metadata property to which you assign a string full of HTML right there in the component's TypeScript code in lieu of having a path to a file for HTML and other (Angular) markup.

Pressing Ctrl and the period together in Visual Studio Code...

...lets you loop in an import in TypeScript for something missing its import.

Can't resolve all parameters for...

This error in an Angular application suggests a circular reference. It's all your fault.

 
 

Addendum 6/4/2018: This also shows up when you don't have @Injectable() at a service.

the leading underscore as a JavaScript naming convention

Alright in C# this would typically be used for a class-wide private variable that is otherwise in camel case and is different from other private variables in camel case by way of its class-wide in availability. Fine. In JavaScript there is no public and private and encapsulation is trickier. The leading underscore (with an otherwise camel case name) is used for "public" methods which are really intended to be "private" and which an outside user (maybe using a third party library perhaps) should be wary of just grabbing ahold of and interacting with.

Thursday, December 6, 2018

createSelector allows for memoization of selectors in the Angular Redux way of doing things.

I offer some notes on Redux selectors, their params, and their memoization stolen from a better blog posting. The better blog posting is here. It offers this example of using params with selectors:

this.counter = this.store.pipe(
   select(fromRoot.getCount, { multiply: 2 })
);

 
 

An example of the memoization is:

export const getCount = () =>
   createSelector(
      (state, props) => state.counter[ props.id],
      (counter, props) => counter * props.multiply
   );

 
 

Some of the curious template-side markup Tim Deschryver gives for finding a customer by id (once the customers are available) and then showing it's name is:

{{ (customers | async)(id).name }}

 
 

RxJS stands for Reactive Extensions in JavaScript. I kinda thought the rx in RxJS and NgRx might be short for Redux, but that is not the prescription.

console.timeStamp() and Major GC

You run the console.timeStamp(); command kind of like console.log("foo"); only this will put ticks in a timeline at the Performance tab of Google Chrome Developer Tools. There are a couple of timelines herein. There is a big timeline and you may make a selection there and see just that bit of the timeline zoomed in in a second timeline. I wish the folks making Adobe Premiere had been smart enough to make a second timeline like this so one didn't have to zoom in and out all of the time. Adobe Premiere is so claustrophobic. I digress. Anyhow there is also an "Event Log" tab at a second set of tabs you will notice after a recording and if you watch Angular's doings you will see "Major GC" in here for the garbage collection. I like the corny name they gave it. We totally have some serious garbage collection going on y'all.

synthetic properties in Angular 7

Angular animations are synthetic properties apparently. The best description I can find of synthetic properties online is that they are seemingly Angular properties such as a word not in quotes but in square brackets inline at an Angular template's tag for something which behave differently than one would expect from Angular markup. The examples I see in this one bad thing I found online for my bad explanation here have a leading at symbol before the word in the square brackets which is indeed a bit different in appearance too.

to memoize

You may make a pure function memoized and that means, in computer science terms, that some of the inputs and outputs in the pure function are progressively cached as they are calculated. This improves performance. It is kinda like the hyperfast reflection stuff I suggest here in that regard.

Apache JMeter

..is a load testing tool.

ng-deep is expensive and to be deprecated

The replacement is going to have to do with some magic to do with the shadow DOM.

Angular Language Service

It offers intellisense for Angular stuff. You may run it in Webstorm or Visual Studio Code.

NgRx Parameterized selectors

These are called props. It looks like that when you do a .select for a selector that you would have a second property (chasing getStuff in this example) which would be a JSON object of props. Typically, the object would just be made right there with open and close curly braces right there for readability.

See your JSON that is in one big string in an indented and easy-to-read shape.

https://jsonformatter.curiousconcept.com is an online tool for this.

Detach elements from change detection in Angular 7.

You can do this with ChangeDetectorRef using the .detach() and after the fact you may still call .detechChanges() to have a looksee. Note that the ngDoCheck lifecycle hook and many others may run even with the OnPush ChangeDetectionStrategy in play.

You can have too many DOM nodes and you can nest DOM nodes too deep.

The "Audits" option mentioned here will report on this problem if there is a problem.

more regarding TSLint

Following up on this, TSLint will also flag imports that are unused in TypeScript classes and console.log occurrences.

npm linking

The global installs of stuff will put a symlink in a global locale where a global package is actually installed back to npm's machinery so that npm knows it is there and then a second association to the global locale in an individual instance of node_modules. symlink means symbolic link or soft link.

Shift-Delete in Windowsland will delete stuff (files) while skipping the recycling bin.

This can be the fastest way to get rid of the node_modules folder. It may be wise to rename the node_modules folder to something else before the delete so that you may also be recreating it with npm install while it is deleting.

artifactory

This is a place to store stuff in the cloud. JFrog Artifactory is a way to go for Azure. I'm not sure what the J in JFrog means nor why the frog party either.

Wednesday, December 5, 2018

There are quite a few Observables keywords that I have not used before.

Today a coworker had a pipe in which first an Observable which was doing polling forever was being merged with an Observable that would squawk if the polling took too long, then first() was called to bring back either the squawking or the successful result from the polling, and finally .switchMap was used to make the Observable of Observable of any just an Observable of any. .mergeMap is different from .merge in that .merge will merge Observables into Observables of Observables while .mergeMap tries to append to a different sequence of Observables. .from maps to an Observable and you may use .from to make an array of "foo", "bar", "baz", and "qux" an Observable that runs through the four things. Obviously, if you just put this to the UI templates with the async pipe you are just going to see the "qux" which might make you wonder why you should care. If you are looping through four actions for the Redux store, that is a bit different right? This is how one emits multiple things with a side event.

the Fibonacci sequence

It gives us the golden spiral. The first two numbers are both the number one and every number in progression afterwards is the sum of the last two numbers like so: 1, 1, 2, 3, 5, 8, 13, 21, 34...

Amazon Alexa

AVS (Alexa Voice Service) is Amazon's service for understanding your voice so that you may interact with the internet of things, or at least some devices, with voice recognition.

ng- versus ng2- versus ngx-

You will see a lot of ngx- pet projects maintained by people who are not the Angular team and which are not released on the same versioned cadence as the Angular team's stuff. So what does the wacky ngx stand for? Angular extensions? No. There were a lot of tags and other names with a leading ng- in the AngularJS stuff and these were originally swapped out with ng2- upon version 2 of Angular. This has given way to ngx- which has a less specific version wherein that version is not version 1. ng stands for Angular.

here we go with Angular 7!

Per this, if something like this has thousands and thousands of records...

<ng-container *ngFor="let mouse of mice">
   {{mouse.squeak}}
</ng-container>

 
 

...while you are scrolling through it all you may drop the unseen items out of the DOM to improve performance like so:

<cdk-virtual-scroll-viewport style="height: 100px;" height="50">
   <ng-container *cdkVirtualFor="let mouse of mice">
      {{mouse.squeak}}
   </ng-container>
</cdk-virtual-scroll-viewport>

 
 

You will notice both the height set by the style tag and the other height. You have to have the height setting or Angular 7 will blow up red to the console. A setting of zero will disable all caching. So what does this setting do? Does it denote how may items may sit in the DOM at once? A coworker thought it was also literally a second height in pixels yesterday. Neither of us know yet. We also don't know if this stuff will play nicely with the infinite scrolling which allows one to progressively load thousands and thousands of records. This stuff does not play nicely with items that are not consistent in size. There is a change-to-be in the experimental CDK stuff that allows one to place the autosize keyword at the outermost of the two tags immediately above and this attribute allows the CDK to guess at an average size for inconsistently sized items.

 
 

Addendum 12/6/2018: height should really be itemSize

Tuesday, December 4, 2018

409

This is the status code for: "failed to load resource"

cleaner tumblr?

...is actively trying to get rid of all of its adult content. It has recently suggested a difficulty in trying to filter out child porn from the "good" porn, but I do not think that is really what is going on. Instead ever since Verizon bought Yahoo there has been a progressive clean up underway.

karma-stacktrace

It is an npm package for trying to give you a better stack of stacktraces for Jasmine/Karma tests.

Atom Keymap

It is a plugin for Visual Studio Code for allowing some of the hotkeys in the Atom editor to work in VS Code.

git commit -a

This says of this variable (the scarlet letter) for this Git command line command that it: "Includes all currently changed files in this commit. Keep in mind, however, that untracked (new) files are not included."

UNIX Epoch time

This is a count of the number of seconds that have elapsed since the beginning of the year 1970. In 2038 an Int32 type in C# will no longer be able to contain the number and horrible things will happen, horrible being a subjective term. The capital X in datetime formatting in moment.js returns this value like so:

alert(moment().format.("X"));

Monday, December 3, 2018

Visual Studio Team Services has been renamed Azure DevOps.

No more VSTS.

ghetto actions in the Redux pattern

Instead of having objects like this, an older approach is to just have magic strings for the actions. Either way they get used in case/switch logic in the reducers to find the right function.

.of in Observables

In contrast to the usual holding open of an ear, this is going to get something for an Observable once and then be done with it. It is like using an Observable as a promise. http://rxmarbles.com this has some details on the machinery of the various Observables keywords and it really shows off how simple .of is.

 
 

Addendum 12/5/2018: .of will actually take whatever is handed into it and then make an Observable out of it so that you may hand a promise to an Observable that will run once in this manner but otherwise what I suggest above is bad.

"changing" store objects in Angular Redux while not mutating state

There are a couple of ways to ensure a new object with a new pointer.

  1. the spread operator
  2. Object.Assign
  3. deep copy
  4. the "deep clone merge function" of redux.utility.ts which has a lot of wacky rules and exception cases and maybe should be avoided

 
 

Addendum 12/4/2018: Item 4 above is bad. The lodash way could serve as a replacement however:

var foo = _cloneDeep(bar);

 
 

Addendum 12/6/2018: should be cloneDeep not _cloneDeep

the @Effect decorator and the trailing dollar sign naming convention

The side effect model for the @ngrx way to go for Redux can be found here. You are going to use the @Effect decorator with this stuff like so:

@Effect() handleFailure$: Observable<any>;

 
 

...and like so:

@Effect({dispatch:false}) handleFailure$: Observable<any>;

 
 

You need the {dispatch:false} when you have an effect that does not kick off another action. Also note that the trailing dollar sign naming convention denotes that a variable is an Observable. In jQuery a leading dollar sign at a variable name denotes a DOM element by convention, but in this case we have rhyming names for all of the Observables in lieu of alliteration.

.map versus .switchMap

Beyond what .map does .switchMap will do some flattening so that if you are mapping to Observables and you are mapping Observables of Foo, Bar, Baz, and Quz you will not get Observables of Observables of Foo, Bar, Baz, and Quz but instead just Observables of Foo, Bar, Baz, and Quz. The nesting is ironed away.

ngx-translate

It offers internationalization for Angular.

git cherry-pick

This actually takes the diff out of a commit and just stamps it to another branch without any regard to whether or not it makes sense or if the larger spots in code where code is being replaced are really still in the same places.

There was a performance problem with Ruby at the Ruby runtime.

This is one of the reasons you don't hear about this stuff anymore. It was the future like Silverlight was the future.

Sunday, December 2, 2018

optional properties at an interface in TypeScript

Use a question mark immediately after the name like so:

interface Cat {
   Name: string;
   Lives: number;
   Birthday?: Date;
}
let cat: Cat = <Cat>{
   Name: "Frank",
   Lives: 9
}
alert(cat.Name);

 
 

You make an "optional" property at a class in the same way.

Saturday, December 1, 2018

The export keyword in TypeScript compiles to JavaScript that loops in the AMD pattern.

There it is again under the hood. That is how that magic works.

It is possible to use Angular 2 and up with just JavaScript and no TypeScript.

I don't know how to do this and I don't want to think about it. It is also possible to run TypeScript at the browser (Internet Explorer) without compiling it down to JavaScript and I don't recommend that either.

Don't new up classes like interfaces in TypeScript.

Which is better?
let cat = new Cat();
cat.Name = "Frank";
cat.Lives = 9;
 
let cat:Cat = <Cat>{
   Name: "Frank",
   Lives: 9
};
Well, if you cast JSON to a class as you might an interface (as shown here) you will sidestep the constructor which isn't cool. I hate it that I cannot make a new class in TypeScript as I can in C# by just breaking into curly braces and assigning all properties upon a new up. I hate it that I have to assign all of the properties in a onesies and twosies manner. Yet, that is the way to go. Rats!

GDE stands for Google Developer Expert

...Google's version of Microsoft's MVP (Most Valuable Professional)

Friday, November 30, 2018

struggling to understand Injectors for the CDK modals of Angular 6

I tried to follow this and this to no avail. In the end I just decided to solve the problem my own way with some singleton state which holds an object like so:

import { President } from '../models/president.model';
import { OverlayRef } from '@angular/cdk/overlay';
export class ModalMetadata {
   overlayRef: OverlayRef;
   president: President;
   
   public closeAction(){
      if(this.overlayRef) {
         this.overlayRef.dispose();
         this.overlayRef = null;
      }
   }
}

 
 

My service is such:

import { Injectable, OnDestroy } from '@angular/core';
import { Overlay } from '@angular/cdk/overlay';
import { President } from '../models/president.model';
import { ModalMetadata } from '../models/modalMetadata.model';
import { ModalComponent } from '../layout/modal.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { Router } from '@angular/router';
import { ISubscription } from 'rxjs/Subscription';
@Injectable()
export class ModalService {
   private backingStore: ModalMetadata;
   private subscription: ISubscription;
   
   constructor(private overlay: Overlay, private router: Router) {
      this.subscription = router.events.subscribe(()=> {
         if (this.backingStore) this.backingStore.closeAction();
      });
   }
   
   public open(president:President) {
      const filePreviewPortal = new ComponentPortal(ModalComponent);
      if (!this.backingStore) this.backingStore = new ModalMetadata();
      this.backingStore.president = president;
      if (!this.backingStore.overlayRef) {
         this.backingStore.overlayRef = this.overlay.create();
         this.backingStore.overlayRef.attach(filePreviewPortal);
      }
   }
   
   public getSingletonState():ModalMetadata {
      return this.backingStore;
   }
   
   ngOnDestroy(){
      this.subscription.unsubscribe();
   }
}

 
 

I have some inversion of control in TypeScript going on and thus there is a contract for the service. It looks like this:

import { President } from '../models/president.model';
import { ModalMetadata } from '../models/modalMetadata.model';
export class ModalContract {
   constructor() {}
   public open: (president:President) => void;
   public getSingletonState: () => ModalMetadata;
}

 
 

My component that I spit out in a modal looks like this:

import { Component, OnInit } from '@angular/core';
import { ModalMetadata } from '../models/modalMetadata.model';
import { ModalContract } from '../contracts/modal.contract';
@Component({
   selector: 'modal',
   templateUrl: './modal.component.html',
   styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit {
   private modalMetadata: ModalMetadata;
   
   constructor(public modalContract: ModalContract) {}
   
   ngOnInit() {
      this.modalMetadata = this.modalContract.getSingletonState();
   }
   
   close() {
      this.modalMetadata.closeAction();
   }
}

 
 

The template for the component is super simple. You will note that you may click an X to close to modal! Also you may have noticed above that the modal closes itself if you navigate away elsewhere.

{{ modalMetadata.president.Name}}... <a (click)="close()">X</a>

 
 

To use this stuff just call the open method in the service. This is all an better bake out of what I originally wrote about here.

 
 

Addendum 12/1/2018: I guess the "singleton state" isn't really a singleton as the state mutates. No... I spoke too soon. A singleton doesn't have to be constant. It's OK.