Friday, February 28, 2020

Dunning-Kruger is the opposite of imposture syndrome!

Check out the chart for overconfidence. I'm seen a fudged graph like this for Ballmer's Peak before. Don't ask me what ZME stands for. Also what's Wikimedia?

Wednesday, February 26, 2020

swatting

If you are doing this you are falsely reporting that someone is breaking the law or that someone else is in danger.

JavaScript in 2018 and 2019.

2018 gave us the spread operator and 2019 Object.fromEntries which reverses Object.entries allowing you to hand in key/value pairs to make an object.

the ECMAScript 2015 deconstruction

The proper way to use the ECMAScript 2015 deconstruction suggested here is:

for (let [key, value] of Object.entries(object1)) {
   console.log(`${key}: ${value}`);
}

lock keys

Num Locklet's use the number values on the arrow keys
Caps Locklet's type in all capital letters!
Scroll Lockmodify the arrow key behaviors with regards to scrolling

Tuesday, February 25, 2020

blocking versus deadlocks in T-SQL

This offers that if a resource is blocked by way of being used by one T-SQL statement, a different T-SQL statement will just wait until the resource is freed up. In deadlocks there is more than one resource to be had to do the thing for the two T-SQL requests and one T-SQL statement gets a deadlock on one thing while the other is thus routed to the other actor by default given what it cannot do.

Monday, February 24, 2020

I watched yet another five minute chunk of the Blazor intro video I found.

Following up on this and this, this is offered for a debounce lookup feature:

@code {
   string searchQuery;
   bool isSearching;
   CancellationTokenSource currentSearchCts;
   Location[] locations = new Location[0];
   bool noResults;
   
   string SearchQuery
   {
      get => searchQuery;
      set
      {
         searchQuery = value;
         if (!string.IsNullOrEmpty(searchQuery))
         {
            _ = SearchDebounced(searchQuery);
         }
      }
   }
   
   bool IsSearching => isSearching || currentSearchCts != null;
   
   [Parameter]
   public EventCallback<Location> LocationChanged { get; set; }
   
   async Task GetLocalWeather()
   {
      isSearching = true;
      var geolocation = await GetlocationService.GetLocationAsync();
      var currentLocation = await
            WeatherForecastService.GetLocationByGeolocation(geolocation.Lati
...
      isSearching = false;
      await LocationChanged.InvokeAsync(currentLocation);
   }
   
   async Task SearchDebounced(string query)
   {
      try
      {
         noResults = false;
         currentSearchCts?.Cancel();
         currentSearchCts = new CancellationTokenSource();
         var thisSearchToken = currentSearchCts.Token;
         
         await Task.Delay(500);
         if (!thisSearchToken.IsCancellationRequested)
         {
            var results = await WeatherForecastService.GetLocationByTest(query);
            if (!thisSearchToken.IsCancellationRequested)
            {
               locations = results;
               noResults = locations.Length == 0;
               currentSearchCts = null;
            }
         }
         
         StateHasChanged();
      }
      catch (Exception ex)
      {
         Console.Error.WriteLine(ex.StackTrace);
      }
   }
   
   void LocationSelected(ChangeEventArgs e)
   {
      var locationName = (string)e.Value;
      var selectedLocation = locations.FirstOrDefault(l => CityState(l) == locationName);
      if (selectedLocation != null)
      {
         searchQuery = null;
         noResults = false;
         locations = new Location[0];
         LocationChanged.InvokeAsync(selectedLocation);
      }
   }
   
   string CityState(Location location) => $"{location.LocalizedName},
         {location.AdministrativeArea.
...
   
   string GetSearchClass() => IsSearching ? "search-icon spinning" : "search-icon";

 
 

Some of the markup added:

<LocationSearch LocationChanged="LocationChanged" />

 
 

Later on there is talk of digging out the geolocation from the browser with JavaScript. Blazor has interop capabilities with JavaScript. AspNetMonsters.Blazor.Geolocation is a NuGet package that does the work already. An IJSRuntime is the type for a JavaScript interop like so:

var result = await jsRuntime.InvokeAsync<Location>
      ("AspNetMonsters.Blazor.Geolocation", requestId);

 
 

The parameters after the first one are generic parameters that will get past on to JavaScript and the generic parameter is the return type.

discards in C# 7

When you assign something to a variable that only has an underscore for a name (and you didn't make the underscore as a variable yourself) you are making a throwaway assignment to a variable that will just die without use. It is a discard. Part of the reason for this is that you may now, as of version 7 of C#, hydrate several variables from a tuple and you may not want all of them. Some can be discards.

Sunday, February 23, 2020

Celery

It's both one of the eight vegetables in V8 (even though I always thought it was just meant to be decorative) and it is an architectural pattern that involves message queues. Messages go into AMQP queues and workers pick up what is in the queues. Meh.

Saturday, February 22, 2020

ERwin SQL

ER for Entity Relationship... This is a tool that allows for relational layouts for database tables like the .edmx thing in the C# space.

Friday, February 21, 2020

Peacock

It will be the NBC (the National Broadcasting Company) streaming service. NBC has a peacock in its logo.

Wednesday, February 19, 2020

datalist and output in HTML5

The datalist here is a type-to-complete feature for a type-what-you-will field. You could match a canned answer basically, or not. The output displays the results of a calculation.

Tuesday, February 18, 2020

In the mainframe space, Hogan is for banking.

old stuff like OS/2

Yesterday, I watched another five minutes of the intro-to-Blazor video I found the day before yesterday.

Following up on this, App.razor looks like so:

<Router AppAssembly="@typeof(App).Assembly">
   <Found Context="routeData">
      <RouteView RouteData"@routeData"
            DefaultLayout="@typeout="@typeof(MainLayout)" />
   </Found>
   <NotFound>
      <LayoutView Layout="@typeof(MainLayout)">
         <p>Sorry, there's nothing at this address.</p>
      </LayoutView>
   </NotFound>
</Router>

 
 

In another example, Forecast.razor starts out like so:

@page "/"
@implements IDisposable
@inject IWeatherForecastService WeatherForecastService
@inject PinnedLocationsService PinnedLocationsService

 
 

@page above denotes what is routable while @code { lets you break into C# code right there in a razor view. A call out to TemperatureUnitPicker.razor in a .cshtml file looks like this:

<TemperatureUnitPicker @bind-TemperatureUnit="temperatureUnit" />

 
 

The .razor files may have "code behinds" so to speak. You just make a .cs file with the same name as the razor file only with .cs on the end so that it ends in razor.cs. Append "Base" on the end of the default name for the class and make it derive from ComponentBase. Then loop it in at the .razor file like so:

@inherits TemperatureUnitPickerBase

 
 

An onclick event midstream in an input tag:

@onclick="SwitchTemperatureUnit"

 
 

Loop in a using statement in a .cshtml file up top like so:

@using System.Threading.Tasks

 
 

Make an input that is ultimately a select list perhaps???

<input list="locations"

 
 

"locations" above is filled in like this:

<datalist id="locations">
   @foreach (var location in locations.Take(10))
   {
      <option value="@CityState(location)"></option>
   }
</datalist>

Monday, February 17, 2020

IOptionsMonitor in C#

I think it wraps external dependencies together in a bag for dependency injection stuff.

red aluminum!

Check out the Galaxy Chromebook. I kinda want one. I learned about it today at Eden Prairie Center.

I cannot hide the mat-paginator tag for a MatPaginator with *ngIf in an Angular 8 application without sabotaging the tag when it should work.

Well this suggests jamming this in the tag like so:

[ngStyle]="{display: isLargeScreen ? 'block' : 'none'}"

 
 

In the TypeScript class for your component you probably also want to conditionally turn off the MatPaginator's assignment.

if (this.isLargeScreen) {
   this.dataSource.paginator = this.paginator;
}

Sunday, February 16, 2020

SignalR for Blazor Server today!

Today I thought of Blazor and I watched the first dozen minutes of this and in doing so I learned that while we are still waiting until midyear for the Blazor WebAssembly stuff, the Blazor Server version, which will be more sluggish in performance and not include a disconnected mode, is here to goof off with now. Visit blazor.net for more. You will need .NET Core 3.0, Visual Studio 2019 version 16.3 or better, and the Blazor templates stuff for making a new project. I made a project. My Program.cs parallels that of the video more or less with more or less this in it:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Tinker.UserInterface
{
   public class Program
   {
      public static void Main(string[] args)
      {
         CreateHostBuilder(args).Build().Run();
      }
      
      public static IHostBuilder CreateHostBuilder(string[] args) =>
         Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
               webBuilder.UseStartup<Startup>();
            });
   }
}

 
 

Startup.cs in turn looks like so. You may see where we are both using the server-side rendering and then pointing to a _Host.cshtml file as the front door to the application.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Tinker.UserInterface.Data;
namespace Tinker.UserInterface
{
   public class Startup
   {
      public Startup(IConfiguration configuration)
      {
         Configuration = configuration;
      }
      
      public IConfiguration Configuration { get; }
      
      public void ConfigureServices(IServiceCollection services)
      {
         services.AddRazorPages();
         services.AddServerSideBlazor();
         services.AddSingleton<WeatherForecastService>();
      }
      
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
         if (env.IsDevelopment())
         {
            app.UseDeveloperExceptionPage();
         }
         else
         {
            app.UseExceptionHandler("/Error");
         }
         app.UseStaticFiles();
         app.UseRouting();
         app.UseEndpoints(endpoints =>
         {
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
         });
      }
   }
}

 
 

_Host.cshtml in turn has this in it. The video calls out the blazor.server.js callout in JavaScript and the Razor syntax two lines above it as "what is special" herein. SignalR is used to communicate back to the server from the client. It fakes out the magic to be for real midyear, if you believe all that. I'm not sure I am buying in.

@page "/"
@namespace Tinker.UserInterface.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>Tinker.UserInterface</title>
   <base href="~/" />
   <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
   <link href="css/site.css" rel="stylesheet" />
</head>
<body>
   <app>
      @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
   </app>
   <script src="_framework/blazor.server.js"></script>
</body>
</html>

 
 

The video has you make Component1.razor as a Blazor object. It looks like this. The video puts emphasis on how the usual onchange event is swapped out with oninput here so that the event should trigger whenever we type in the control.

@using Microsoft.AspNetCore.Components.Web
<h3>Component1</h3>
<input @bind="message" @bind:event="oninput" />
<p>message: @message</p>
@code {
   string message;
}

 
 

Around the twelve minute mark the video was coughing up this as the way to call out to what is immediately above in a Razor .cshtml view. It looks a lot like what is in _Host.cshtml with App swapped out with Component1. I don't know where Component1 comes from other than the file name honestly. I don't see a deeper tie in yet.

@(await
      Html.RenderComponentAsync<Component1>(RenderMode.ServerPrerendered))

DBeaver

It's an open source SSMS of sorts. I bumped into this trying to understand when I would ever want to use SQL instead of T-SQL. This and this touch on it. I think the answer is never. I think I could use SQL with Microsoft's stuff if I really wanted to like I could use VB.NET. It is, I suspect, a base for the other types of SQL to branch from.

 
 

Addendum 2/17/2020: The DB part of the name would stand for database. Duh.

I saw Michael Jordon speak on geofencing at AngularMN on Wednesday night.

Version 5 of Ionic came out the very day of this talk. Micronaut, as a microservices framework for Java, Groovy, and Kotlin was described as an alternative to Spring Boot. Versions 1 and 2 of CoffeeScript are apparently quite a bit different. I remember seeing, I think, Derick Bailey badmouth CoffeeScript based on the fact that you might not like the JavaScript it compiles to. I wonder if the two different versions vary in how they ultimately compile or if there are things in the first version you just cannot do in the second version. Rollbar is error logging for Python. It will send an SMS message when a new bug appears. Fantasy Strike is some sort of fighting game like Mortal Kombat. Signal.IO apparently tracks errors at the client (yes, JavaScript) and, as its npm write up suggests, it "is a realtime application framewrork for building Web API based on WebSocket instead of HTTP" complete with the framewrork typo. Catalina is the latest name for the latest version of macOS. High Sierra is a different version. El Capitan and Mountain Lion are OS X versions and OS X and Mac OS X beforehand are really just different names for what is now macOS. Universally unique identifier is what uuid stands for. Well, enough random things. I should probably talk about the talk Michael Jordon gave. This may be the last talk at virtuwell and the last monthly talk too. Michael, one of the AngularMN organizers volunteering himself as a presenter due to how hard it is to find presenters, bemoaned how hard it was to find presenters and suggested that the group may fall over to a quarterly meeting format in compensation. I suspect this particular meeting could be the last one with Black Sheep Pizza and could mark the last time, for a while, that I'll have a reason to venture into St. Paul. Michael works at Medtronic and suggested the HCU (healthcare utilization???) data is as hard to come by as speakers for his meetup and hence, Medtronic is trying to cook a lot of it up themselves with a geofence or two in the mix. If you have an implantable loop recorder (ILR) implanted in your chest broadcasting signals, maybe the device can "know" when you visited a hospital based upon the geofencing around a hospital which could be a circle with a single point and a radius or a polygon of multiple points (verities with latitude and longitude pairings) around a building. Some other characters visiting the talk had an application that probation officers used in lieu of ankle bracelets to make sure peeps on probation didn't stray out of their county. Other visitors had an inventory application telling them how far away, as a crow flies, a particular chunk of equipment was. The app didn't use Google Maps to cough up driving directions as some things, Caterpillar excavators for example, could not be moved as nimbly as a car might move. Users use "street view" in Google Maps to make judgments about obstacles for this sort of circumstance. There was some talk of what you get for free with Google Maps. For example, you get twenty fences, leading to a strategy in which nineteen fences are drawn and a twentieth fence encloses them. When your user strays beyond the twentieth fence, the nineteen closest fences are recalculated. Google Maps stay valid for up to twenty-four hours and Google gives you up to $200 of API calls for free so why not make a pool of maps in a cache and serve stuff out of your pool in the name of keeping costs down. When someone is done using a map it may just go back in your little cache for the remainder of its time to live, no? Someone suggested using layers overtop of Google Maps to manage pins or drawings. Michael, using Ionic, spun up an app he live coded with these Ionic CLI commands:

  1. ionic start geofence-demo tabs --capacitor
  2. cd geofence-demo
  3. ionic serve

 
 

So, yes, we have Capacitor in the mix here to try to have at some of the lower levels of phone, this time in the name of geolocation not, for instance, the camera. Radar is used for the geofencing itself. It has an SDK. With Radar you may have one hundred geofences for free and up to ten thousand users for free. Radar can "know" if someone is just driving through a geolocation or actually stopping there based on checks for service. This is called stop detection. There are other dev tools for detecting geolocation spoofing too. The probation guys eluded to as much. Some of Michael's Ionic markup looked like so:

<ion-header>
   <ion-toolbar color="primary">
      <ion-title>
         Fences
      </ion-title>
   </ion-toolbar>
</ion-header>
<ion-content>
   <ion-spinner style="margin: 10px auto; display: block;" *ngIf="loading"
         name="crescent"></ion-spinner>
   <ion-list>
      <ion-item *ngFor="let f of fences">
         <ion-label>
            <h2>{{f.description}}</h2>
            <p>lat: {{f.gemometryCenter.coordinates[0]}}</p>
         </ion-label>
      </ion-item>
   </ion-list>
</ion-content>

 
 

Michael said he was using webhooks out to a Heroku API. From there Twilio sends a text message. CocoaPods was being used for dependency management (think npm or NuGet only for the Mac) for Xcode to dig up the Radar stuff. You cannot just use .startTracking in Radar but instead you have to have something like .trackOnce().then((result) => { and have the .startTracking nested inside as otherwise the .startTracking won't fly. In modern Mac Safari dev tools, you may connect your phone in easily to your laptop to test on your phone, etc. Michael's TypeScript sister pairing with the markup above looked like so:

@Component({
   selector: 'app-tab3',
   templateUrl: 'tab3.page.html',
   styleUrls: ['tab3.page.scss']
})
export class Tab3Page {
   fencesPromise: Observable<any>;
   fences: any = [];
   loading: boolean = false;
   
   constructor(public httpClient: HttpClient) {
   }
   
   ionViewWillEnter() {
      this.loading = true;
      this.getFences();
   }
   
   getFences = (theclick = null) => {
      this.fences = [];
      
      const: httpOptions = {
         headers: new HttpHeaders({
            'Content-type': 'application/json',
            'Authorization': 'environment.radarKey
         })
      }
      
      this.fencesPromise = this.httpClient.get('https://api.radar.io/v1/geofences',
            httpOptions);
      
      this.fencesPromise.subscribe(data => {
         this.fences = data.geofences;
         
         if(theclick) {
            theclick.target.complete();
         }
         
         this.loading = false;
      }, error => {
         connectableObservableDescriptor.log();
         this.loading = false;
      })
   }
}

Saturday, February 15, 2020

random alt tech things that came up at today's Dungeons and Dragons session

  1. FVEY (the five eyes) is orchestration of intelligence sharing across Australia, Canada, New Zealand, the United Kingdom and the United States while FISA (Foreign Intelligence Surveillance Act) in tandem with FVEY allows for America to spy on Americans by having Brits spy on Americans, exploiting a loophole.
  2. The term yeet can mean approval or it can mean to throw something.
  3. Dailymotion, LBRY (for library?), BitChute, and Banned.Video are all video sites.
  4. eMule is a torrent file-sharing thing for Linux.
  5. qmap.pub (wherein the q is for Q level security clearance which is supposedly superior to that of the president) is something like 4chan or 8chan (now 8kun).

Friday, February 14, 2020

an online tool for removing line breaks from a blob of text

http://removelinebreaks.net/ seems legit.

Your new iPhone still has the classic ringtones of the older iPhones!

at: Settings > Sounds & Haptics > Ringtone > Classic ...you will find "Bark" for example! I have an iPhone X with iOS version 12.4.1. "Classic" comes last in order after all of the others in alphabetical order in the Ringtones section of "Ringtone" (not the "Store" section nor the "Alert Tones" section).

Using the var keyword with C# 7.0 tuple deconstruction.

Following up on this, this...

private (int numby, string descript) GetLucky()
{
   int thirteen = 13;
   string meaning = "luck!";
   return (thirteen, meaning);
}

 
 

May be sucked on like this:

var (numby, descript) = GetLucky();

Fortnite

Don't ask me what the Fortnite llama piñata is all about but Fornite the game has three modes and the most popular is a free-for-all everyone-fight-everyone first person shooter thing in which up to one hundred jam at once and the last man standing is the winner. I have never played and I was not going to write of it, but just last night I read that the IRS (Internal Revenue Service) will no longer tax the in-game currency. You may just stockpile the currency without taxation it would seem.

Thursday, February 13, 2020

Match against a CSS media query from within JavaScript!

if (window.matchMedia("(max-width: 991px)").matches) {

SortDirective is not defined

If you see this error, the CommonModule of '@angular/common' is not looped in.

OverflowException

This is the silent error that occurs in C# when you wrap the wheel, when you count a numeric type up past its upper bounds and it ends up with a funny setting somewhere in its range as opposed to higher up yet as expected.

Wednesday, February 12, 2020

an example of using .some in JavaScript to find even one match to some complicated condition in a search of records

This has this which gives either true or false and in this particular case: true

const array = [1, 2, 3, 4, 5];
const even = (element) => element % 2 === 0;
console.log(array.some(even));

Vocollect VoiceLink

This is a voicemail service on a private network. You pay a small, reoccurring fee for it. Other peeps on the network can blast out robocalls to voicemail mailboxes.

The e in Apple IIe stands for "enhanced" it seems.

A coworker mentioned this in a my-first-computer way yesterday. It looks like it showed up in 1983.

Use .toFixed in JavaScript to round a number to two decimal places!

This has this example:

var num = 5.56789;
var n = num.toFixed(2);

How do I slap a consistent footer onto an Angular Material table in the name of having, for example, a sales total for all sales?

Below the closing for the table detail which has an opening like so...

<td mat-cell *matCellDef=

 
 

...you want:

<td mat-footer-cell *matFooterCellDef>
   Do what you will...
</td>

 
 

Below this row...

<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>

 
 

...you want:

<tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>

Use querySelectorAll instead of querySelector to get something other than the very first match in a Jasmine/Karma test!

it(`should place '123' in first table detail`, () => {
   const compiled = fixture.debugElement.nativeElement;
   const mainTable = compiled.querySelectorAll('table')[1];
   expect(mainTable.querySelector('td').textContent).toContain('123');
});

Trigger ngOnChanges on an Angular 8 component within a Jasmine/Karma test!

beforeEach(() => {
   fixture = TestBed.createComponent(GridComponent);
   component = fixture.componentInstance;
   component.contents = {
      columns: [
         { name: "Id" },
         { name: "FullName" },
         { name: "CityState" }
      ],
      data:[ { "Id": "1", "FullName": "Ty Ng", "CityState": "NY, NY" }],
      uniqueId: 1
   };
   component.ngOnChanges({
      contents: new SimpleChange(null, "contents", true)
   });
   fixture.detectChanges();
});

I awoke this morning remembering a conversation with John Locke from FramesDirect.

He was telling me that he liked PHP better than ASP.NET and his reason was that PHP would render what it could of a web page up until the point where it broke. ASP.NET just gave that red and yellow screen of death with the ketchup and mustard coloring.

Tuesday, February 11, 2020

handing template gunk from one component to another in an Angular application when there is a middleman component to pass through

I am making sort of a generic grid sort of centered around the Angular Material paginated list. A user may specify both rows and columns and the columns may be of a number of "types" like so:

<ng-container [ngSwitch]="column.type">
   
   
<!-- Copy -->
   <ng-container *ngSwitchCase="0">
      {{record[column.name] | findValue:column}}
   </ng-container>
   
   
<!-- Hyperlink -->
   <ng-container *ngSwitchCase="1">
      <a [href]="record[column.hyperlinkUrl]">{{record[column.name] | findValue:column}}
            </a>
   </ng-container>
   
   
<!-- Button -->
   <ng-container *ngSwitchCase="2">
      <a href="#" (click)="runEventNotHyperlink(column.buttonClickEvent, record,
            dataSource.data)">{{record[column.name] | findValue:column}}</a>
   </ng-container>
   
   
<!-- Template -->
   <ng-container *ngSwitchCase="3">
      <ng-container *ngTemplateOutlet="templateInstance; context:
            {communicatedColumn: column, communicatedRecord: record}">
      </ng-container>
      <ng-content></ng-content>
   </ng-container>
   
</ng-container>

 
 

Alright, the ngSwitch above shows off what gets barfed into the cell where a particular row and column intersect and the interesting thing to note here is the last of the possibilities wherein someone using the grid may hand in a template. In the TypeScript class for the grid component we have "grid" as a selector and a ContentChild like so:

@ContentChild('templateReference', {read: TemplateRef, static: true}) templateInstance:
      ContentChild;

 
 

Alright, here is an example of nesting the repurposable grid in a larger component and handing in a template for defining what the template columns should look like. Obviously, there could be some ngSwitch logic here as well in the name of swapping between "which column" if you need two custom columns to behave differently.

<h1>Distributors</h1>
<grid [contents]="gridDataWrapper">
      <ng-template #templateReference let-column="communicatedColumn"
            let-record="communicatedRecord">
      <span>{{record[column.name]}}</span>*
      </ng-template>
</grid>

 
 

You can see what this does, no? With the exception of adding a span tag around the cell's contents it just puts an asterisk after what would otherwise be in the cell. I guess the span tag allows for some overarching skinning of the other contents and the asterisk independently. Meh. Alright, in some cases we want a series of these grids to be wrapped up together beneath a set of tabs. The set of tabs should also be a reusable component and it shows one grid at a time like so:

<div class="outerwrapper">
   <div class="topbartabs">
      <ul class="tabs">
         <li *ngFor="let tab of contents; let i = index;" [ngClass]="i==currentTab ? 'activetab'
               : ''"><a href="#" (click)="tabClick(i)">{{tab.tabName}}</a></li>
      </ul>
   </div>
   <grid [contents]="gridDataWrapper">
      <ng-template #templateReference let-column="communicatedColumn"
            let-record="communicatedRecord">
         <ng-container *ngTemplateOutlet="tabInstance; context:
               {communicatedTabColumn: column, communicatedTabRecord: record}">
         </ng-container>
      </ng-template>
   </grid>
</div>

 
 

"grid-tabs" is the selector for this component and in the component's TypeScript we have:

@ContentChild('tabReference', {read: TemplateRef, static: true}) tabInstance:
      ContentChild;

 
 

How do we communicate a template into this from a wrapping component that will bleed all of the way down to the grid component? We do so like so:

<h1>My Profile</h1>
<grid-tabs [contents]="tabsDataWrapper">
   <ng-template #tabReference let-tabcolumn="communicatedTabColumn"
         let-tabrecord="communicatedTabRecord">
      <span>{{tabrecord[tabcolumn.name]}}</span>*
   </ng-template>
</grid-tabs>

 
 

As I type this up, I wonder if two grids in two tabs could have two columns of the same name which needed different templates. I guess one would have to rename a column upfront before assigning a collection of any to one of the grids to accommodate for that. That kinda sucks, but should I get into gold platting to compensate for that heartache?

T-Mobile and Sprint are to merge into... T-Mobile.

In the U.S. of A., T-Mobile is the third largest mobile carrier and Sprint is in fourth place. (Verizon is first and AT&T second.)

Maybe the aliases for a table in SQL should be readable variables and not one letter encodings.

I'm the biggest hypocrite.

Delete your extra GIT branches from "the server" in Azure DevOps.

Go to "Branches" under "Repos" in Azure DevOps. Click on the garbage can icon by a branch to make it go away.

Micro Focus Unified Functional Testing used to be QuickTest Professional.

UFT/QTP allows for automated functional and regression testing.

Monday, February 10, 2020

a Theory instead of a Fact in an XUnit test

What I have here is probably bad. Instead when you have attributes like so decorating a test:

[Theory]
[MemberData(nameof(Data))]

 
 

This means that the test is not DAMP and that it will be rerun several times over for variations in a collection. "Data" has to be defined somewhere like so:

public static IEnumerable<object[]> Data =>

Set CSS classes and other similar things on FormControl types in TypeScript!

Those specifics get jammed in the curly braces below.

let foo = new FormControl({value: 'Nancy', disabled: true}, Validators.required);

Add an Angular FormControl to a FormGroup in TypeScript!

This offers:

this.myForm.addControl('newControl', new FormControl('', Validators.required));

Scott Gu

...is another name for Scott Guthrie, the veep of the "cloud and AI group" at Microsoft.

Uff da

This is the Minnesotan way to say "Great!" in a really sarcastic way. It is Norwegian in origin. While I am being regional, both Nicollet Island (sits in the Mississippi river) and Nicollet Street in Minneapolis are named for a Joseph Nicollet who made some of the best maps of the upper Mississippi river and some of its tributaries. Nicollet Street is sometimes referred to as "Eat Street" because there are spots to eat along it. I endorse the Nicollet Diner personally.

Saturday, February 8, 2020

I saw Patrick Szalapski speak on refactoring at the Twin Cities .NET User Group on Thursday night.

Unlike most of these events, this one was hosted at General Mills, the makers of Cheerios and Planters Peanuts amongst other things. Elsa Vezino works with Patrick at General Mills and, as she is now a co-organizer of this meetup, she pulled the strings to have us meet deep within General Mills. Patrick Szalapski is at left in the photo here, not the main focus. I took two standalone pictures of just Patrick but then settled on using this photo instead which shows off the tower of pizza slices stacked atop each other that the guy eating salad crafted. I thought it merited stealing a picture. I was waiting for those three books to be given away during the raffle at the end or at least to be addressed in the talk itself but that never happened as fate would have it. From left to right they are the Clean Code tome of Uncle Bob, Feathers' treatise, and finally "Adaptive Code: Agile coding and design patterns and SOLID principles" by Gary McLean Hall which I had not heard of before. I didn't go to the Twin Cities .NET user group in January because it just had a variation of this talk which I had already seen, but Patrick pulled the GitHub source code from that talk and refactored it in front of us. Much of what he did just involved following ReSharper suggestions/practices. At the end he got into the D of the SOLID principals by showing us how to refactor the direct reference to an external dependency midstream in code out to an external dependency behind an interface. Someone in the crowd asked about when to refactor and you want to refactor the thing you are working on, not random points in the code. At the same time the refactoring should not be tied to a particular story or be the main matter of a particular story. You should just do it as you go. It should also realistically be impossible unfortunately for an outside tester, not a dev, to test. Something that came up some was the crunching of several lines of code into one and, yes, with this comes a harder space to debug in. I have often times had to break one clever line of code into many to get at what was going wrong with it.

Friday, February 7, 2020

ng-checked

Inline in a checkbox control in the old AngularJS stuff might govern, by way of its assignment, if a checkbox is checked. See: this

Thursday, February 6, 2020

ClaimAuthorize

It is a little like Authorize only claim-flavored. This has these examples:

  • [ClaimAuthorize(Permission="CanUpdateLedger")]
  • [ClaimAuthorize(Permission="Accounting.Ledger.CanUpdate")]
  • [ClaimsAuthorize("SomeController", "Edit")]

roles vs. claims vs. policies in Identity Server

This suggests that roles include both users and functions (things one may do) while a user is made up of claims. A policy is an authorization frontdoor to see if you may go forward.

Pareto principle

It's another name for the eighty/twenty rule. Romanian consultant Joseph M. Juran cooked up this rule naming it for Italian economist Vilfredo Pareto per Wikipedia which is never wrong.

ClaimsPrincipal in C# magically manages users in such a manner that ReST calls to the same app as the app holding the MVC Razor views where one logged in to begin with have user specs.

My head explodes! How does this work? It must be recognizing something specific in the browser session based on the header communicated. Wacky! Well now there will be no more state across a mishmash of session and cache. If you set a breakpoint at return below on line fifteen, the two variables in the two previous lines get hydrated if you are logged in.

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
namespace Portal.Web.Controllers
{
   [Route("api/[controller]")]
   [ApiController]
   public class JaeschkeController : ControllerBase
   {
      [HttpGet]
      public IEnumerable<string> Get()
      {
         var isInsider = User.IsInRole("Insider");
         var myId = User.Claims.FirstOrDefault(x => x.Type == "MyId").Value;
         return new string[] { "value1", "value2" };
      }
   }
}

 
 

Microsoft.AspNetCore.Mvc.Controller which has the support for views inheirts from Microsoft.AspNetCore.Mvc.ControllerBase (thinner) which has the ClaimsPrincipal called User hanging off of it. My superior thinks the magic is tied to the antiforgery token of MVC.

When bugfix is all one word it is semantically like hotfix implying the code for the fix itself.

In contrast bug fix would be the act of fixing the bug and the roll out, etc.

column sorting at an Angular Material table

This offered some advice, allowing this...

<table mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource">
   <ng-container [matColumnDef]="column.name" *ngFor="let column of
         contents.columns; let i=index">
      <th mat-header-cell *matHeaderCellDef>{{column | findHeader}}</th>

 
 

...to become:

<table mat-table matSort (matSortChange)="sortData($event)"
      class="lessons-table mat-elevation-z8" [dataSource]="dataSource">
   <ng-container [matColumnDef]="column.name" *ngFor="let column of
         contents.columns; let i=index">
      <ng-container *ngIf="!column.isToDisallowSorting; else disallowSorting">
         <th mat-header-cell *matHeaderCellDef [mat-sort-header]="column.name">
               {{column | findHeader}}</th>
      </ng-container>
      <ng-template #disallowSorting>
         <th mat-header-cell *matHeaderCellDef>{{column | findHeader}}</th>
      </ng-template>

 
 

Also I added the following methods to my component, a generic grid that should be able to accomodate any dataset:

   public sortData(sort: Sort) {
      if (!sort.active) {
         return;
      }
      let isAscending:boolean = sort.direction === 'asc';
      let baseType:BaseType = this.contents.columns.find(x => x.name ==
            sort.active).baseType;
      this.contents.data = this.contents.data.sort((a, b) => {
         return this.compare(a[sort.active], b[sort.active], isAscending, baseType);
      });
      this.setStage();
   }
   
   private compare(a: any, b: any, isAscending: boolean, baseType: BaseType) {
      let A:any = this.tryToAccountForNulls(a, baseType);
      let B:any = this.tryToAccountForNulls(b, baseType);
      if (A === B) return 0;
      return (A < B ? -1 : 1) * (isAscending ? 1 : -1);
   }
   
   private tryToAccountForNulls(ab: any, baseType: BaseType){
      if (ab || ab === 0) {
         return ab;
      }
      switch(baseType){
         case BaseType.Array:
            return [];
         case BaseType.Boolean:
            return false;
         case BaseType.Date:
            return new Date(1970, 0, 1);
         case BaseType.Number:
            return 0;
         case BaseType.Object:
            return {};
         case BaseType.String:
            return "";
         default:
            return ab;
      }
   }
}

 
 

The object and array options here are pretty silly, eh? All that I am doing is making a new pointer which cannot be greater than, less than, or equal to a similar pointer so (you guessed it) my if (A === B) return 0; comparison is sabotaged in that regard. Nuts! I could hand in an extra metadata property for which property on an object to sort by I guess. Also, I may need an option for an enum so I could sort by the string values for the enum instead of just the number.

make a slider with Angular Material

<mat-slider min="1" max="100" step="1" value="1"></mat-slider>

Mobile Firefox!

It's a thing for both iPhone and Android. Back in the day you could save bookmarks to a profile (at Firefox) and then have the same bookmarks wherever you used Firefox across many computers.

Error: Found the synthetic listener @arrowPosition.start. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.

Add BrowserAnimationsModule to your imports at the TestBed.configureTestingModule gunk in your failing test to get around this bug.

JavaScript Symbols

These are a primitive types (alongside string, number, undefined, null, and boolean). No two symbols are equal and thus if you use a symbol as the name of a property on an object other code cannot stamp over top of it later on downstream. This has this example:

const NAME = Symbol()
const person = {
   [NAME]: 'Flavio'
}

Maybe you can't return out of a JavaScript forEach but you can set the counter on a for loop past the point of applicability.

This just spits up: "I can sw"

"use strict";
var startMessage = "I can swear. I can joke.";
var endMessage = "";
for (var i = 0; i < startMessage.length; i++) {
   if (startMessage[i] == "e") {
      i = startMessage.length;
   }
   else {
      endMessage = endMessage + startMessage[i];
   }
}
alert(endMessage);

 
 

Hot Jesus! This could be a good tool in your toolkit bug fix boy.

Wednesday, February 5, 2020

If your Windows 10 search bar just shows blank bullshit today...

...there is a cure you can install to hack the registry and turn off Bing Search.

App is to applet what pig is to piglet.

An applet was a small Java application around the turn of the millennium. The only one I ever used allowed one to hand in five labels and five numbers and it would make you a little pie chart.

Tuesday, February 4, 2020

Create some build events in Visual Studio 2019 to loop in (preprep) the Angular gunk in your application?

At this put stuff in "Post-build event command line:" maybe? The commands you would run from a shell?

 
 

Addendum 2/5/2020: The following ends up in the .csproj file:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
   <Exec Command="cd ClientApp npm run build" />
</Target>

Integrate an existing Angular application into a .NET Core 3 MVC and Razor orchestration.

The cheatsheet here (by "admin") starts out with some of what I suggest here, namely running commands (from a command prompt navigated to the root of your application as "Administrator") like so:

  1. npm install -g @angular/cli
  2. ng new ClientApp --createApplication=false
  3. cd ClientApp
  4. ng generate application portal --routing --style=scss
  5. ng add @angular/material
  6. npm install
  7. ng build

 
 

The last of these commands behaves differently than just npm install insofar as it will make a dist folder which the rest of the app will read from when sucking Angular 8 into a view. Also, you will need to run this last command every time you make a change in the Angular stuff to update the rest of the application. Other challenges along the way you may face include this, this, and this as well. This needs to be shoved into a view where you loop in Angular.

<app-root></app-root>
<script src="/ClientApp/dist/portal/runtime-es2015.js" type="module"></script>
<script src="/ClientApp/dist/portal/runtime-es5.js" nomodule defer></script>
<script src="/ClientApp/dist/portal/polyfills-es5.js" nomodule defer></script>
<script src="/ClientApp/dist/portal/polyfills-es2015.js" type="module"></script>
<script src="/ClientApp/dist/portal/styles-es2015.js" type="module"></script>
<script src="/ClientApp/dist/portal/styles-es5.js" nomodule defer></script>
<script src="/ClientApp/dist/portal/vendor-es2015.js" type="module"></script>
<script src="/ClientApp/dist/portal/vendor-es5.js" nomodule defer></script>
<script src="/ClientApp/dist/portal/main-es2015.js" type="module"></script>
<script src="/ClientApp/dist/portal/main-es5.js" nomodule defer></script>

 
 

The way the blog posting in the very first link I give in this blog posting undertakes to summon in the markup here out of /ClientApp/dist/portal/index.html is overkill. Do your own thing. Jam this stuff into a partial.

Stripping @addTagHelper out of _ViewImports.cshtml can somehow sabotage the Razor in a .NET Core 3 application.

The inputs, be they password or checkbox, just become regular fill-in-the-blank inputs.

Monday, February 3, 2020

using Razor TagHelpers?

This will have you making something like this:

using System;
using System.IO;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace Portal.Web.TagHelpers
{
   [HtmlTargetElement("angular-app")]
   public class AngularAppTagHelper : TagHelper
   {
      public AngularAppTagHelper()
      {
      
      }
      
      public string App { get; set; }
      
      public override void Process(TagHelperContext context, TagHelperOutput output)
      {
         //throw new Exception("yikes");
         using (var sr = new StreamReader(AppDomain.CurrentDomain.BaseDirectory +
               @"\ClientApp\dist" + App + @"\index.html"))
         {
            string htmlRaw = sr.ReadToEnd();
            
            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(htmlRaw);
            
            var body =
                  htmlDoc.DocumentNode.ChildNodes.FindFirst("body").ChildNodes.Where(x
                  => x.Name == "script");
            StringBuilder sb = new StringBuilder("");
            
            foreach (var item in body)
            {
               string scriptTag = String.Format("$<script src=\"/ClientApp/dist/{0}/{1}\">
                     </script>", App, item.Attributes["src"].Value);
               sb.AppendLine(scriptTag);
            }
            
            output.Content.AppendHtml(new HtmlString(sb.ToString()));
         }
      
      }
   }
}

 
 

In the name of injecting Angular 2+ gunk into Razor views like so:

<app-root></app-root>
@section Scripts{
   <angular-app app="portal"></angular-app>
}

 
 

\Views\_ViewImports.cshtml gets this in it:

@using Portal.Web.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

 
 

I cannot for the life of me get any of this to work. I cannot set a breakpoint inside of the Process method and land in there. Lame!

Error: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.

Fix this in Angular by putting this in head:

<base href="/">

Appian!

It's more COTS gunk like SharePoint and Pega.

Saturday, February 1, 2020

Wednesday's JavaScript MN meetup had a series of short talks, most notably Andrea Edstrom on accessibility.

Andrea Edstrom, who runs a CodePen meetup herself, was not the first speaker nor the last, but gave the talk with the most meat. Only a Terry Schubring, pictured at left with Brandon Johnson who namedropped Flutter, was scheduled to speak with Ms. Edstrom, pictured immediately below, and he spoke first and then after Andrea spoke three other peeps in the crowd piped up with impromptu ideas for talks and, yep, gave little talks. Terry's talk gave an exposition of a virtual synthesizer he made (um, with JavaScript) that really can just run on a laptop and be a real synthesizer and cost thousands of dollars less than a traditional synthesizer. This esoteric flavoring was not lost in Andrea's presentation either. She referenced WeCo Accessibility Services, a Minneapolis-based accessibility testing company that actually employs handicapped individuals as testers, but there was also some meat on the plate with the parsley while the other speakers just served parsley. Four things to communicate in creative mockups include, firstly, a delineation between what is a hyperlink from what is a button, as sometimes you might want a hyperlink that looks like a button, etc., and, third on the list, a tab order. Items two and four were sort of sisters. The second item was an accessibility name, communicating to the user and telling the user what an HTML element is, while the fourth was a role jammed inline in a tag like roles="rolename" to tell the reader semantically what a thing is and, yes, items two and four could be wildly different. You could have pseudolinks that behave like buttons. I was making one of these at work just this week and then found myself lying awake at night wondering if that stunk. I guess it doesn't have to smell so bad if I follow Andrea's suggestions. She referred to what I would think of as a carousel as a slider, told us to be wary of text overlaying images, and emphasized using semantic HTML tags such as header, nav, footer, and aside. The aside tag is for a sidebar callout. webaim.org and learnui.design help you make color palettes for mockups in a handoff from creative to coders. Storybook, a11y, Lighthouse, and Deque Axe ("The Axe") were all mentioned in the talk as well.

Jason Webb gave a talk on "space colonization" which showed off lines growing outwards at random in something like fractals if you can imagine that randomness too. There were both 2D and 3D treatments to show off. I guess the underlying algorithms were in JavaScript.

Luke Penna showed us paralex images which are made of many 2D images overlaying each other in such a way that a 3D effect occurs as the foreground and background items move differently when someone scrolls a scrollbar. The images themselves are just kept in a series of div tags.

Harrison Nguyen showed us an application he wrote wherein you punch in a zip code and the app recommends clothes for you to wear based upon the weather at that zip code which is gleamed via an API call. PerSuede is the name of his application. He hopes to eventually link recommended clothes to sites that sell the clothes.

The pizza was an hour late and so a huge line formed for the pizza when it did show up. We broke from the other proceedings midstream for pizza.

It was Domino's I know. Andrea mentioned the Domino's lawsuit due to a lack of accessibility. I think a blind person successfully sued due to an inability to use the website.

The line was kind of random like Jason Webb's lines. It bent back on itself in a U shape I suppose.