Saturday, March 30, 2019

On Wednesday night, JavaScript MN offered up Zachary Skalko presenting on how to author one's own npm package!

The venue for the Twin Cities' largest meetup group changed again! This time it was hosted at WeWork Uptown. In his introduction, Brandon Johnson mentioned that one of JavaScript MN's sponsors, Twilio, has bought SendGrid which will allow its cloud communications platform to have a posh way to send emails. Brandon also gave a lighting talk in which he brought up some embroidery web site which seemed to have text growing in font size with every paragraph and he suggested the culprit was an ongoing series of opening "header" tags (did he mean the head tag in HTML?) with no close tag counterparts. Brian Mitchell of C. H. Robinson also gave a lighting talk and his had to do with TypeScript in React. ReactElement | null is a pretty common union type. create-react-app of Facebook was used in his example which utilizes Babel to compile TypeScript. Someone in the crowd noticed <> followed much, much later by </> in Brain's markup amid something he was projecting, wherein the two tags wrapped a bunch of stuff, and asked about it. It turns out that this is a React Fragment. You may use it to wrap a JSX or React.createElement() per Brian. I'll get to what Zachary Skalko (pictured at left) had to say in a moment, but first, while we are already off on a tangent, I'd like to regurgitate a The Law of Demeter slide he had which gave the very specific definition of For all classes C, and for all methods M attached to C, all objects to which M sends a message must be instances of classes associated with the following classes:

  1. The argument classes of M (including C).
  2. The instance variable classes of C.

 
 

(Objects created by M, or by functions or methods which M calls, and objects in global variables are considered as arguments of M.) This Law has two purposes:

  1. Simplifies modifications. It simplifies the updating of a program when the class dictionary is changed.
  2. Simplifies complexity of programming. It restricts the number of types the programmer has to be aware of when writing a method.

 
 

The Law of Demeter, when used in coordination with three key constraints, enforces good programming style. These constraints require minimizing code duplication, minimizing the number of arguments passed to methods and minimizing the number of methods per class. Zach pointed out how easy it is to import one thing into another thing in other languages. For example:

  1. Java
    import java.util.ArrayList
     
  2. Python
    import requests

 
 

In contrast, there are a multitude of ways to navigate such in JavaScript:

  1. ES6
    import $ from 'jquery'
     
  2. CommonJS
    const $ require('jquery')
     
  3. RequireJS (the AMD pattern)
    requirejs(['jquery'], function ($) { /* app logic */})
     
  4. script tag
    <script src="/jquery/3.3.1/core.js"></script>

 
 

You have to navigate all four ways when you make a packet. For example the "classnames" packet does it like so:

if (
   typeof module !== 'undefined' &&
   module.exports
) {
   classNames.default = classNames;
   module.exports = classNames;
} else if {
   typeof define === 'function' &&
   typeof define.amd === 'object' &&
   define.amd
) {
   define('classnames', [], function () {
      return classNames;
   });
} else {
   window.classNames = classNames;
}

 
 

The name for this sort of catchall inclusion seems to be UMD (Universal Module Definition) and I believe rollup.js will help you make this sort of stuff for your code. There may be a rollup.config.js file sitting side by side with your index.js file (if your package is really just one file) and I think you have to have a package.json file for your package too with a name and a version number speced out. The version number has to increment every time you check in. You will need to have an .npmrc file locally to publish packages and https://registry.npmjs.org has one you may get for starters. When you type an npm install command it is going to look to npm.org by default and this locale has a list of registries that it looks to by default including the one at npmjs.org. The command...

npm adduser

 
 

...should log you into the registry and...

npm publish

 
 

...should publish your package. An example of a shebang or sha-bang (or even "hashbang") might be...

#!/usr/bin/env node

 
 

...and I think these allow for header/footer includes in files, but I don't know how they work. These were namedropped in passing. Brian Mitchell is pictured below.

Friday, March 29, 2019

Abandon a pull request in Azure DevOps when it cannot build.

At the big blue button at the upper right that says "Set Auto-Complete" at the pull request, click on the down arrow at the right edge and pick "Abandon" from the menu that appears.

Azure IoT Edge

Collects telemetry data for IoT devices at the "edge" of your network and does reporting, metrics, etc.

RStudio, runs at a server, and is a web-based IDE.

It does not play well with SUSE (Software und System-Entwicklung meaning Software and Systems Development) and you will have to instead use CentOS (Community Enterprise Operating System) which is a different flavor of Linux. Shiny, which offers publishing tools for RStudio, is of GPLv3 which is the third and current version of the GNU General Public License.

Measure

This is an app that lets you drop a pin and then move your smartphone to the left or the right or wherever while it tells you how far you are in distance from where you started. It allows you to measure things, the length of a tabletop, etc.

form-Z

This is another 3D graphics sculpt-away tool like 3ds Max.

Thursday, March 28, 2019

garbage in, garbage out

If you write a function to double a number and you hand in "CAT" as the number, the function won't perform well. The term "garbage in, garbage out" touches on as much in computer science.

BA stands for business analyst.

...digger, listener, runner, prince with the swift warning. Be cunning and full of tricks and your people shall never be destroyed.

Cast the guts of an Excel sheet tab to an HTML table with js-xlsx!

Following up on this, I would really ask that you look to the source code at this to better understand how to get js-xlsx to work out for you. I needed to revamp my two methods given before like so:

processFile(event:any):void{
   let filePath = event.target.value;
   if (filePath && event.target.files && event.target.files.length){
      let file = event.target.files[0];
      var reader = new FileReader();
      reader.onload = function(e:any) {
         var data = e.target.result;
         data = new Uint8Array(data);
         this.processWorkbook(XLSX.read(data, {type: 'array'}));
      }.bind(this);
      reader.readAsArrayBuffer(file);
   }
}
 
processWorkbook(workbook){
   let excelTabs:Array<ExcelTab> = [];
   let counter:number = 0;
   workbook.SheetNames.forEach(function(sheetName) {
      try {
         let html:string =
               XLSX.utils.sheet_to_html(workbook.Sheets[workbook.SheetNames[counter]]);
         html = html.replace("<html><head><meta charset=\"utf-8\"/><title>SheetJS Table
               Export</title></head><body>","");
         let excelTab:ExcelTab = {
            Name: sheetName,
            Html: html.replace("</body></html>","")
         };
         excelTabs.push(excelTab);
      }
      catch(exception) {
         excelTabs.push({ Name: sheetName });
      }
      counter++;
   });
   console.log(excelTabs);
}

 
 

The reason for the try/catch is that I have seen error messages where it (the tool) cannot make the HTML for a tab. It vaguely says something about how it cannot split on undefined. The error is bubbling up from within js-xlsx itself and I have not yet set breakpoints in there to troubleshoot. ExcelTab is just something I tossed together in TypeScript that looks like this:

export interface ExcelTab {
   Name:string;
   Html?:string;
}

DAX

The data analysis expressions language is used with tabular data in Power BI. The BI part of Power BI stands for business intelligence obviously and DAX has a bunch of functions and operators that allow one to make query expressions in this denormalized space. MDX or Multidimensional Expressions is for multidimensional cube data as opposed to tabular data. MDX is to multidimensional what DAX is to tabular.

Wednesday, March 27, 2019

I am getting started with js-xlsx to redisplay what is in an Excel sheet up to the UI in Angular 7 app in the name of giving users a visual sanity check.

Alright, assuming something like this, I can remake my uploadFile method like so to at least be able to loop through the names of the tabs in the Excel sheet. This is how far I got today.

uploadFile(event:any):void{
   let filePath = event.target.value;
   if (filePath && event.target.files && event.target.files.length){
      let file = event.target.files[0];
      var reader = new FileReader();
      reader.onload = function(e:any) {
         var data = e.target.result;
         data = new Uint8Array(data);
         this.processWorkbook(XLSX.read(data, {type: 'array'}));
      }.bind(this);
   }
}
 
processWorkbook(workbook){
   workbook.SheetNames.forEach(function(sheetName) {
      alert(sheetName);
   });
}

 
 

Define the XLSX variable at the top of your component with the other imports like so, and by the way you have to have the first line here to get the TypeScript compiler to stop complaining about the require in the second line. This is the way you to that.

declare var require: any;
var XLSX = require('xlsx');

 
 

You may install xlsx via npm like so and that means there probably is also a better way to grab ahold of it as an import that I have not yet uncovered:

npm install xlsx

 
 

The tool is described here and here. (View the source HTML at the second URL.)

 
 

Addendum 3/28/2019: This is kinda weak. There is more to see here.

betamax

...was the rival to VHS. I've never actually seen a betamax tape in real life. I guess there were 8-track tapes before cassette tape too. I don't think I've held one of those in my hand either.

Tuesday, March 26, 2019

Show the version in an Angular 7 application.

How do get the version out of package.json in an Angular 7 application into a variable in environment.ts so that I may turn around and use that variable in the greater application to display in the footer what the version number is or something?

declare var require: any;
const { version } = require('../../package.json');
export const environment = {
   numberOfTacos: 13,
   production: false,
   version: <string>version
};

When scheduling an appointment in Outlook, pick a room!

At the "Scheduling Assistant" ("Scheduling" here) pick a time slot. Then at the "Room Finder" at the far right, or available via the "Invited Event" ribbon, change the "Show a room list:" dropdown to pick a categorization of rooms such as "Main Campus Conference Rooms 1st floor" which will load a list of specific rooms to pick from!

Monday, March 25, 2019

article 13

Wikipedia suggests that the "The Directive on Copyright in the Digital Single Market 2016/0280(COD), also known as the EU Copyright Directive" holds article 13 which attempts to protect the copyrights on memes and gifs and everything else that is an uploaded image. Per the rule, any uploaded image must past through a filter that tries to verify if it is legal! Whoa! There is to be a vote on this tomorrow.

when you visit "Backlogs" beneath "Boards" at Azure DevOps and all you see is stories from the current sprint

Infuriating! That's not what is supposed to be here! Click the funnel icon at the upper right to "Filter" which will open up a grey toolbar with some controls on it. Pick "Iteration" from the toolbar and then check only the checkbox for "Backlog" therein. There! I solved that problem!

Babar, NBot, Bunny, Dino, and Casper are names of malware.

I was looking back at old Facebook photos and I noticed this on a slide from Black Hat. I do not know what the N in NBot stands for. It is probably NOT the .NET convention used in NServiceBus and NHibernate.

Sunday, March 24, 2019

SIL Open Fonts License

Aka, OFL, this is mentioned on page 295 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis and is an open source license offered up by SIL International. SIL used to stand for Summer Institute of Linguistics. AKA stands for also known as. duh.

Thursday, March 21, 2019

Using OFFSET in T-SQL pagination.

SELECT *
   FROM dbo.People
   ORDER BY Name
   OFFSET 200 ROWS
   FETCH NEXT 10 ROWS ONLY

 
 

There are variants of this wherein NEXT is replaced by FIRST and/or the ONLY keyword is left off, but I do not recommend those.

Angular's build-to-dist-folder convention and its parallels to web forms

Alright, you may access a private method in an Angular component from its template unlike how you may access a private method in a code behind from its web form, however, when you go to run...

npm run build-prod

 
 

...the private method will likely be unacceptable and you will not be able to package up the Angular app because of it. Make these methods public.

SolMan

It's SAP's Solution Manager and it has bunch of stuff, integrated content, monitoring, meh...

I heard secondhand yesterday that Stanford, University of California (Berkley), and Ohio State are the best schools for UX.

There is a Foundations in Design Thinking Certificate that one may get called IDEO. IDEO (eye-dee-oh) is the name of a company after which IDEO University or IDEO U was named. I don't think the name means anything.

SonarCloud

SonarCloud and SonarLint are other SonarSource offerings like SonarQube and are vaguely also to do with keeping your code clean and of "quality" etc.

Wednesday, March 20, 2019

open source for ABAP!

There is a lot of it! There is an ABAP SDK for Azure to allow the pipelines of Azure DevOps to drive some CI for SAP. abapGit allows an SAP server to chitchat with a Git repository.

LRS has a print server for SAP!

LRS stands for Levi, Ray & Shoup. (Richard H. Levi, Roger Ray, Bob Shoup)

Object Windows Library (OWL)

It's a C++ Framework for easily building desktop apps for Windows environments.

npm audit

...runs some sort of security audit against your code. More scary yet, you may tell npm to "correct" what it finds with:

npm audit fix

Microsoft PowerApps

In 2005 I once read a good chuck of Wrox book on web forms that taught you how to make a web forms app without any C# or VB.NET and instead just by way of the drag and drop web forms controls. Obviously, a connection string to a database was one of the drag and drop controls. I read from this stupid book in the early days of Headspring before Hurwitz and Palermo showed up basically because I didn't know any better at the time. Anyhow, Microsoft PowerApps should be something similar in modern times. Just toss together a canned app with canned controls. It will work with mobile devices and it will work with Power BI.

Amazon's Rekognition

It's facial recognition software.

let first = first;

This will get the first item in a collection in an *ngFor in an Angular 7 application and put it to a variable called first. There is also a last too. Use these like so:

<div *ngFor="let commodity of commodities; let last = last;">

Apply the pending explicit migrations before attempting to generate a new explicit migration.

Catch the database up with your migrations!

Tuesday, March 19, 2019

TypeError: Assignment to read-only properties is not allowed in strict mode

Get around this pitfall in Internet Explorer by changing assignments to style to instead be assignments to style.cssText! It does not break Google Chrome! I started with this:

var loop = function(){
   let offsetHeight:number = document.getElementById('content').offsetHeight;
   let heightStyle: string = "height: " + offsetHeight + "px;";
   var widemenu:any = document.getElementsByName('widemenu');
   if (widemenu && widemenu[0]) {
      widemenu[0].style = heightStyle;
   }
   var narrowmenu:any = document.getElementsByName('narrowmenu');
   if (narrowmenu && narrowmenu[0]) {
      narrowmenu[0].style = heightStyle;
   }
};
var interval = setInterval(loop, 500);

 
 

I revamped like so:

var loop = function(){
   let offsetHeight:number = document.getElementById('content').offsetHeight;
   let heightStyle: string = "height: " + offsetHeight + "px;";
   var widemenu:any = document.getElementsByName('widemenu');
   if (widemenu && widemenu[0]) {
      widemenu[0].style.cssText = heightStyle;
   }
   var narrowmenu:any = document.getElementsByName('narrowmenu');
   if (narrowmenu && narrowmenu[0]) {
      narrowmenu[0].style.cssText = heightStyle;
   }
};
var interval = setInterval(loop, 500);

I'm struggling to get the Material Icons to work and I might just skip it for the time being.

To use these, you should be able to have a CSS style like so:

font-family: 'Material Icons';

 
 

It doesn't want to work in Internet Explorer without some doing. I think polyfills.ts needs this in it:

import 'hammerjs';

 
 

I tried to put...

"hammerjs": "^2.0.8",

 
 

...in package.json and rerun...

npm install

 
 

...but that was not the cure-all. The way to use this stuff is to have something like so:

<span>accessibility</span>

 
 

...styled as suggested above to show the "accessibility" icon in lieu of the word accessibility itself.

MS stands for Microsoft.

I don't think that was explicitly stated elsewhere at this blog.

Monday, March 18, 2019

notes from troubleshooting Octopus variable swapping at appsettings.json!

My attempt to get this working proved painful. The problem was that in the "YourNameHere Template - Roslyn - VariableReplacement" step the "JSON Target Files" setting needed to be changed from appsettings.json by itself to:

appsettings.json
appsettings.Development.json
appsettings.Test.json
appsettings.Production.json

 
 

The reason the variables had to be written to the other files is that the other files were being used in other environments. For example in Development appsettings.Development.json was being referenced instead of appsettings.json and that was creating a scenario in which connection strings were empty strings until the problem was fixed. In the "Update Web.Config Environment" step under "Process" in Octopus' interface there was a PowerShell script like so at "Inline Source Code":

$path = 'IIS:\Sites\' + $webSiteName;
Write-Output "Website name $webSiteName"
Add-WebConfigurationProperty -Filter "/system.WebServer/aspNetCore/environmentVariables" -Verbose -PSPath $path
      -AtIndex 0 -Name Collection -Value
      @{name='ASPNETCORE_ENVIRONMENT';value=$ConfigurationEnvironment}

 
 

This is using the ConfigurationEnvironment variable out of the "Variables" in Octopus' UI wherein "Development" is the Development option, "Test" is the Test option, and, yes, "Production" is the Production option. Alright, in figuring this out I learned a few interesting things along the way:

  1. If Citrix NetScaler is is managing having an application straddle two different webservers using IIS, then if you stop an application pool at one of the webservers Citrix NetScaler should be smart enough to pick up on this and route all traffic to the second webserver.
  2. The ".NET CLR version" in IIS 8.5.9600.16384 for an application pool for a .NET Core API should be set to "No Managed Code" and not ".NET CLR Version v4.0.30319" instead.
  3. At Windows Server 2012 R2, if you type "Event Viewer" at the "Search" magnifying glass and look through what is in the Event Viewer, you may refresh what you see by picking: Action > Refresh
  4. Type "Environment Variables" at the magnifying glass and then click "Edit the system environment variables" to get the "Advanced" tab at a "System Properties" dialog box where you may click the "Environment Variables..." button to see a list of applicable variables.

clientHeight versus offsetHeight in JavaScript

This suggests that clientHeight includes padding...

var clientHeight = document.getElementById('myDiv').clientHeight;

 
 

...while offsetHeight includes padding, borders, and scrollbars too!

var offsetHeight = document.getElementById('myDiv').offsetHeight;

Alibaba is the Amazon of China I hear.

...and by Amazon I don't mean the river.

Saturday, March 16, 2019

You might just want to refresh an unloaded project in Visual Studio Preview 2019.

I saw one of these after a merge today and at first assumed that I had botched the clean up of the .csproj file in question. Ultimately, I right-clicked on the project in Visual Studio Preview 2019 and picked "Reload Project" to fix the problem.

I've made my stupidity all the more stupid.

This "improves" upon this.

Friday, March 15, 2019

Esri

...makes mapping software that works with GIS.

Avocode

...let's you look at documents made by Adobe Photoshop and Adobe XD and the like.

third normal form

A smart person I work with was telling me that the third normal form is one in which database tables are pretty much dictionaries in which there are only two columns just for keys and values. I suppose there would be bridge tables with key-to-key pairings too. My coworker suggests that this is a trapping of high ideology that does not work in real life.

TLA+ is yet another programming language.

Temporal Logic of Actions is what the TLA stands for.

.gitkeep

If you want to commit an empty folder in the GitHub paradigm you can put an empty .gitkeep file in the folder. You cannot commit a truly empty folder.

pseudo mapped drive to "Sites" folder in IIS

In this line of PowerShell the IIS:\Sites\ corresponds there.

$path = 'IIS:\Sites\' + $webSiteName;

not too fast

A judge named Josh Thacker of Spalding County, Georgia (South of Atlanta a bit) threw out Wentworth Maynard's lawsuit against Snapchat siting a dangerous precedent that would be set should things go the other way. I'm not sure if it is called the speed filter or the speedometer filter but Snapchat had a filter which would tell you how fast you were going in terms of MPH (miles per hour). Anyhow, some teenage girls or maybe just some young twenty something girls tried to get a car up to a three digit number herein if memory serves so that they could take selfies of themselves with the filter afloat and they ended up tapping cars with Wentworth Maynard's car and there was a modestly terrible accident in which no one died but he wound up with permanent brain damage. He tried to sue Snapchat over its unsafe filter alongside the driver, a Christal McGee. We see warning labels on things all the time right? These are brought about by lawsuits and Ralph Nader and more lawsuits. However... should this stuff collide with free speech? I don't think so. I applaud this decision in contrast to this decision.

Thursday, March 14, 2019

Integrated Security=true; versus Trusted_Connection=True;

There is more or less no difference. This touches on as much some. While I am on this Integrated Security=SSPI; is more or less like Integrated Security=true; too.

Make the variables in appsettings.json environment-swappable with Octopus.

Get started:

  1. Go to Octopus' web UI.
  2. Search at the "Projects" tab for your project.
  3. Go to the "Process" tab at the left.
  4. Drill into the "Update Web.Config Environment" option, assuming that is one of your steps. (If this step is greyed-out, click on the three dots in a vertical line at its upper right corner and pick "Enable" from the options there.)
  5. Click "JSON Configuration Variables" herein.
  6. Fill in line items for:
    • appsettings.Development.json
    • appsettings.Production.json
    • appsettings.Test.json
  7. Go into Visual Studio 2019 Preview and copy what is in appsettings.json to...
    • appsettings.Development.json
    • appsettings.local.json
    • appsettings.Production.json
    • appsettings.Test.json
  8. Back at the "Variables" tab beneath the "Process" tab at the left setup variables for .json file variables with breakouts for Development, Production, and Test named Development, Production, and Test. If you are like me and you cannot add a new variable with "Add Another Value" and "Add To List" then pick "Duplicate Variable" from the menu at comes out of clicking on the three dots in a vertical line at the upper right of any one variable. (This seems like an outright bug in Octopus!) Variable names need to match up with .json settings names. If you are going to drill down beyond the top tier seperate the name chunks in Octopus with colons as you might with dots in JavaScript.
  9. Make all the variable slots in appsettings.json have empty values with open quotes immediately followed by closed quotes or something comparable and similarly put #{variable} in the same slots in appsettings.Development.json, appsettings.Production.json and appsettings.Test.json
  10. Put #{variable} in your deployable files and #{variable} should not really just only say #{variable} put instead the variable part of #{variable} should be replaced with your specific variable name as denoted in Octopus.
  11. Right-click on your UI project in Visual Studio 2019 Preview and pick Debug from the settings pane that appears with Application, Build, Build Events, Package, Debug, Signing, TypeScript Build, and Resources down the upper left edge. Herein there is probably one environment variable named ASPNETCORE_ENVIRONMENT and you should change it's value to "local" as "Development" no longer applies.
  12. On the Angular frontend side, the head of a headless app, you will need to have a similar breakout for environment.ts. You will find a production configuration in angular.json and you should make development and test copies. You will want to make environment.development.ts and environment.test.ts to sit along with environment.ts and environment.production.ts too. At the "Update Web.Config Environment" step under CONFIGURE FEATURES, the "Substitute Variables in Files" setting will make the most of the #{variable} trick and you sort of have to use this with environment.ts stuff. However, for appsettings.json you may just check "JSON Configuration Variables" and this will try to match up a variable name in Octopus to a parameter in the JSON object in making replacements.

 
 

Things to try when it does not work:

  1. In the "Update Web.Config Environment" Process option, click on "Inline Source Code" and look at the script being used to find the appsettings.json files at IIS. It will either be PowerShell, C#, Bash or F#. Maybe you have the wrong file path.
  2. Whenever you want to experiment with a change herein in attempt to kick the build awake, instead of recommitting some code to increment the version number which will likely be required to have a successful build, you may click "Create Release" in Octopus above the left nav with Overview, Process, Variables, Channels, Releases, and Settings in it and then click Version to manually change the version number. I would recommend just bolting a letter onto the end of the current version number instead of incrementing the build number as you might when checking in code honestly. When you click "Save" here at the upper right there will be a button for "Deploy to Development" to take its place and on the other side of that a button that says "Deploy" to click before the build gets underway. Between "Deploy to Development" and "Deploy" you will have to cancel the last build if the last build was both created manually like this in this hacky way and also a failure.
  3. Go to "Releases" at Overview, Process, Variables, Channels, Releases, and Settings to drill into the particular deployments and look at their errors. The errors should reveal the names of the servers being pushed to so that you my remote desktop in there and poke around some too.

get-childItem -path $path

In PowerShell this will give you a verbose list of files at the path specified in the $path variable complete with permissions and the time of the last modification.

manifest.json

Loop this in at a web page like so inside the head tag:

<link rel="manifest" href="manifest.json">

 
 

It is a file full of metadata about the page. An example might be:

{
   "name": "FunStuff",
   "short_name": "FunStuff",
   "theme_color": "#1976d2",
   "background_color": "#fafafa",
   "display": "standalone",
   "scope": "/",
   "start_url": "/",
   "icons": [
      {
         "src": "assets/icons/icon-72x72.png",
         "sizes": "72x72",
         "type": "image/png"
      },
      {
         "src": "assets/icons/icon-96x96.png",
         "sizes": "96x96",
         "type": "image/png"
      }
   ]
}

Ceremity is no more!

Alright, when you visit http://www.ceremity.com/ you are taken to https://www.pdisoftware.com/welcome-ceremity-visitors/ so I would guess that Vlad sold his company. I think Ceremity was the best job I've yet had. An eight month stint was the perfect amount of time truth be told.

Wednesday, March 13, 2019

using .indexOf on an array in JavaScript is just like using .indexOf on a string

You will get -1 if there is not a match and otherwise you will get the numeric position of the first match.

Gopher is a TCP/IP protocol distributing and searching documents.

Yawn.

IBM is to buy Red Hat.

They don't want Red Hat for its Linux. Red Hat has a bunch of cloud stuff. IBM will attempt to compete with Azure. Red Hat OpenShift is some sort of container tech like Docker. Ginni Rometty (IBM's CEO) gambles. You know IBM may be an eleventh of the Dow Jones Industrial Average and the biggest slice of that pie, but it has been comatose for decades. Watson isn't going anywhere. It's time to change the subject, eh?

Tuesday, March 12, 2019

Drop all changes and roll back to what just came out of source control using the git command line commands.

git clean -df
git checkout

Queries in Azure DevOps

These are under Boards amongst Work Items, Boards, Backlogs, Sprints, Queries, Plans, and Calendar. You may do here what you might expect. Instead of seeing all the stories you may make a query to only see a list of stories that have to do with you, etc.

KPMG

Is one one of the big four auditors along with Deloitte, Ernst & Young, and PricewaterhouseCoopers per Wikipedia. These guys help you with your taxes as a company and investigate your means of doing things along those lines. They have a worldwide footprint. K for Pieter "Piet" Klijnveld, P for Peat Marwick, M for Frank Wilber Main, and G for Reinhard Goerdeler

Huawei stole tech from T-Mobile?

The Chinese company's chief financial officer Meng Wanzhou has been arrested in Canada.

Cameron and Tyler Winklevoss have their own cryptocurrency called Gemini!

At SXSW (South by Southwest) the Winklevoss twins advertised it as the "most regulated" cryptocurrency as if to suggest you should not be scared of volatility with regards to it.

Monday, March 11, 2019

I saw Robert Boedigheimer speak on performance optimizations at the Twin Cities .NET User Group on Thursday night.

.dev is a top level domain that is now available. Robert Boedigheimer has his own .dev domain name and, yes, email address. Per Robert, eighty to ninety percent of the time that is spent waiting is spent waiting on resources and not the server interacting with databases or your C# code struggling to deal with string concatenation without you using a StringBuilder. (Oh man, every time you add something to a string you are really destroying and recreating the string because strings are immutable. Oh no!) Forget server-side concerns? Robert suggests it is your CSS and JavaScript that is making your site load slow, and, yes, slow load time is bad. Robert mentioned that Amazon and WalMart experimented with making their web presences load one hundred milliseconds slower and saw a one percent drop off in sales. I am not convinced that there is no reason to worry about server-side performance. This touched on that some and moreover, I have seen the pain of server-side performance problems firsthand at, well... I won't say. Alright, we can have problems like that on the client side too. Robert suggests the three big things you can do to improve performance are:

  1. make few HTTP requests
  2. send as little as possible
  3. send it as infrequently as possible

Eric Lawrence's Fiddler was acquired by Telerik in 2012 but is still available for free and still a good tool for seeing what is going on with your web traffic in the name of putting your finger on a problem. "Speed Index" as a metric is a number of milliseconds to when the viewport is mostly viewable while "Time to Interactive" is a comparable metric for how long it takes before a user may actually click stuff. webpagetest.org gives you waterfall diagrams (timelines) of where time is spent in bringing up your site. Keynote has become Dynatrace and you can pay this company a fee for "synthetic monitoring" in which they hit your site and report back to you what they thought of its snappiness. RUM (Real User Monitoring) is a way to recreate a user's steps through interacting with your site. As you use Chrome it's reporting back to Google (unless you forbid its telemetry data mining) and thus you may go to https://www.thinkwithgoogle.com/feature/testmysite to look up by URL the performance for any one site and cross-compare the performance of competitors to your own. Robert recommends checking the enable dynamic compression checkbox in IIS (it's a checkbox somewhere) to turn on HTTP compression which evaluates "Accept-Encoding" headers in requests and returns the result's header compressed by GZIP or Deflate or Brotli. Leverage the browser cache by allowing images to be cached at the client for thirty days as suggested by the server. To make IIS make such a suggestion, pick "Set Common Headers" under "HTTP Response Headers" and then set the setting for expiration as X number of days. If a resource is slow to be found, what is going on? Is it latency or is it bandwidth? It turns out that it is probably latency, the number of hops across routers one must journey to reach your server. Make your images "closer" to those requesting the images with a CDN (content delivery network). Limelight is a CDN. It is possible to have protocol-less links like so that will figure out for you if they resolve to http or https addresses.

<img src="//cdn.example.com">

 
 

You need to have fallbacks when utilizing a CDN. If jQuery is not loaded, pull the document from the server not the CDN, etc. With regards to bundling and minification, HTTP/2 is a gamechanger. The old paradigm of jamming all of your JavaScript into one file so that that one file equates to one request may be forgotten and you may now have multiple files which HTTP/2 will aggregate into a single request. This also means that when you change one of the small files the client does not have to get anew all of your JavaScript! Use SVG for logos. JPEGs are smaller than PNG files. Robert was not a fan of having images embedded in the HTML itself as a bunch of goofy gibberish that cannot be cached. There is a trick for having images of different sizes for responsive design too. Observe:

<img srcset="/images/flagBridge-128.jpg 128w, /images/flagBridge-256.jpg 256w,
      /images/flagBridge-512.jpg 512w" src="/images/flagBridge-default.jpg">

 
 

Obviously, the reason to indulge this is to load images of smaller file sizes when possible. Don't choke your mobile user with big images, etc. jpegtran is a command line tool that removes unnecessary metadata from JPEG images. The geolocation of where a photo was taken, what type of camera it was taken with, and what shutter speed was used are amongst the stupid things in almost every JPEG file that is adding to its bloat. Fiddler's Image Bloat will put images of red bricks ontop of images to partially or almost completely cover them to show just how much of a file's size is metadata versus the actual image. Robert showed off examples of images that were far more metadata than anything else. Abode Photoshop allows for batch compression of images. JPEG has two formats and the progressive format (as opposed to "normal") will show you a fuzzy image at first that gets clear as the image loads and this happens as opposed to the top loading first and then the image slowly revealing (loading) downwards. If you buy images and take out the metadata that is perfectly legal. data-src instead of src and data-srcset instead of srcset are ways to lazy load content after everything else is loaded so that you may then drag in the less vital content after the page is ready to go. You might have to drag in some JavaScript to get this to work. I'm not certain. If you use the async keyword like this:

<script src="/js/alert1.js" async></script>

 
 

The content in question will not block other downloading content while it tries to download. If you swap out async with defer in these circumstances the deferred scripts will still be aggregated in asynchronously without holding up the main content but will wait for each other a little bit and end up running in the specified order. Resource hints are newish. Here is a way to preload everything at a second web page that you bet users will visit next.

<link rel="prerender" href="http://www.example.com/">

 
 

URLs are seen in a case-sensitive light in most browsers such that variations in casing in three calls to the same URL can result in three independent trips outward for a resource. HTTP Strict-Transport-Security or HSTS lets you tell browsers what should only be available via https in lieu of http. Font Squirrel will allow you to take a font you are to use online and trim it down to just the characters you want reducing its size. Take out all of the wacky Korean characters you'll never use, etc. Lighthouse is an analytics tool as is https://developers.google.com/speed/pagespeed/insights/ It was recommended to do performance reviews with Fiddler and to use Corel PaintShop Pro as an inexpensive photo editor. If you are using fonts .woff2 files are smaller in file size than .woff files. webp is twenty percent smaller than JPEG but only supported by Google Chrome. Use the "Performance" tab in Google Chrome Developer Tools to record a movie for resources coming into play in a SPA app to find out where a bottleneck might be in your performance.

There is a "default database" per user login at MSSQL Server.

It is kinda useless, but if you rename the default database for a user it can set the setting to null and prevent the user from logging into the server. Lame!

SolarWinds Orion

Orion Monitoring allows a business to monitor and correlate its data.

Sunday, March 10, 2019

Web Hypertext Application Technology Working Group

Per Wikipedia (never wrong right?), WHATWG as an organization came up with its own HTML5 which eventually became the basis for the real HTML5. Party!

Saturday, March 9, 2019

At AngularMN Wednesday night I saw David Stanich speak on Angular Elements.

Custom elements are a JavaScript trick to allow you to make up your own HTML tags which are able to work and do stuff by way of supporting JavaScript. Think of how the selector tag for a component loops in a component at the DOM in an Angular application, only imagine doing that outside of Angular or React or Vue in an environment where there is no guarantee of support for anything beyond vanilla JavaScript. These creatures can survive in most any environment. Web components in contrast to custom elements loop in the Shadow DOM and HTML templates as well. Angular Elements is the Angular way to make web components. You author in Angular and then push out some code that can run outside of Angular independent of Angular albeit perhaps with the trick of including a slimmed-down version of Angular in the source code.

customElements.define('my-element',
   MyElement);

 
 

...is an example of creating a definition for a custom element in JavaScript and that in turn should allow you to have an HTML tag like so:

<my-element some-attribute="a value">
</my-element>

 
 

You have to have a tag with at least one hyphen in it to guarantee that the tag you dreamt up will not collide with a new HTML tag that could exist one day. I believe the attributes have to have hyphenated names too and what is more you cannot pass JSON objects in these inputs. You have to pass strings. You can always stringify JSON and then parse it to get it across this hurdle. This stuff does not work in Microsoft's browsers, just Google Chrome. There are polyfills to address as much, but by now custom elements probably sound kinda ghetto, huh? They are in their infancy as an emerging technology and not yet something you should bet the farm on so to speak, or as David put it: "Don't put them in your money-making code." Maybe they could be fun to just goof off with in the name of getting your head around something you likely will eventually have to care about. connectedCallback() is a callback event for custom elements kind of like ngOnInit in the Angular space and disconnectedCallback() is the event for when the custom element is destroyed. attributeChangeCallback() is an event for reacting to a change at one of the attributes. Coming with the Ivy renderer which will be optional in Angular 8 and forced upon you in Angular 9, you will have Angular Materials. David authored what he showed off to the crowd in the alpha of Angular 8. One of the weaknesses of modern Angular as opposed to AngularJS is that you have to have a full SPA (Single Page Application) app overarching everything and there is no longer a way to just have Angular nested in a div. Of course, now there is a way with Angular Elements to some limited extend. You may inject Angular within JSP (Java Server Pages) or Jade for example. Someone in the crowd asked if you could have Angular Elements inside of an Angular application. The answer was yes. Can the two crosstalk? Maybe if they are of the same runtime (version/environment) though David seemed unsure. Angular CLI does not support builds nor offer boilerplate code for Angular Elements yet which is yet another thing that makes this stuff so painful. I guess while I am on a roll, let me mention that just because this stuff looks like Angular components you should not think that you can have events back out in the same way with the familiar parenthesis syntax. Instead you have to write boilerplate JavaScript to catch events. In tsconfig.json in Angular, when baking Angular components, you will want to set your target for transpilation to ES2015. Use AOT (ahead of time) compilation. If you have the same Angular Element several times on the same page a lot of boilerplate code will be repeating itself in terms of what is coming up to the browser. Custom Elements Everywhere has some scoring on how well custom elements play with existing frameworks including wacky things you've never heard of like Dio.js and Dojo 2 (There is a Dojo 2???). React does not rate so well in their eyes. Use...

gzip -v elements.js

 
 

...at the CLI to GZIP (GNU zip) to, I suppose, minify code and the like. The -v is for verbose and you don't want to rename variables to terser things. Something random that was mentioned was that a "computed" in Vue's paradigm is a way to call a function by a plain text name. I've ran into David Stanich a few times at these events before. He works for IBM in Rochester, Minnesota and commutes in to virtuwell's office in St. Paul, Minnesota for AngularMN once a month. To hear him speak, IBM has a building in Rochester that is a mile long. Thanks to Keegan Jones (left) and Will Buck (right) for hosting this event.

 
 

Addendum 11/1/2019: By Angular Materials above I surely meant Angular Elements. Also Angular Materials is really Angular Material.

There is a ForEachAsync in C#.

It's a Lambda expression thingy. You can do it off of an IQueryable holding a collection.

await myCollection.ForEachAsync(mc =>
{
   stupidCounter = stupidCounter + mc.Id;
});

 
 

There is also a ToListAsync and the way you use it is to do a .ToListAsync() on the end of the thing that makes your IQueryable. Your IQueryable thus must become a List and later on when you do a foreach it can just be a regular foreach loop instead of the ForEachAsync trick. You will need the await keyword after the equals sign too so that the overall assignment starts out like so:

List<Aardvark> myCollection = await ...

SaveChangesAsync

await _context.SaveChangesAsync(); inside of an async method will be the thing you are awaiting when you call the method with await outside the method elsewhere in code. This was recommended to me to read on this subject.

InvalidOperationException: The connection does not support MultipleActiveResultSets.

When you see this error, the compiler must know that your async/await stuff is jacked as best as I can tell.

 
 

Addendum 3/12/2019: The problem for me was calling some async stuff before an Entity Framework 6 transaction which needed to be moved into the transaction.

Thursday, March 7, 2019

Did you know that when you run .NET Core at IIS it will make on the fly a Web.config file from appsettings.json and other applicable things.

I guess this will NOT happen on a Mac or in other environments.

CSTE

Certified Software Tester! It's a cert you can get!

Microsoft Edge is going to just become a reskinned version of Google Chrome.

Microsoft is going to stop developing its browser and admit that Google has won the browser wars. Edge will still kinda look like Edge and may have some Edginess like the use of Bing as the default search engine perhaps (would not surprise) while using Google Chrome's Chromium engine to render the DOM when it actually coughs up HTML.

What's a zero-day exploit?

It is any security hole you don't know about. The day you learn about it is day zero of you dealing with it. Kinda a stupid name. chrome://settings/help in Google Chrome should tell you "Google Chrome is up to date" or tell you how to upgrade the version. You'll want to do this because there is some zero-day stuff version 72.0.3626.121 would fix. The loophole to close up has to do with running nasty code at a sandbox in Chrome.

Alt-Tab

At Windowsland this takes you back to the last app you were touching if it is still open. Alt-Tab again would thus toggle you back to the thing you just left. Alt-Tab will thus let you toggle back and forth between two applications. Pressing Alt-Tab once will allow you to hold Alt and keep pressing Tab to navigate about all the open applications you have as well.

Center-clicking on a link at a website will open the URL at a new tab in Google Chrome.

On a PC (personal computer, a Windows-flavored computer and not a Macintosh), center-clicking means clicking the scrollwheel.

throwing errors in JavaScript!

This will kick off the else condition below:

try {
   throw 'Can you see this?';
}
catch(error){
   if (error.message){
      this.loggingContract.Log(error.message);
   } else {
      this.loggingContract.Log(error);
   }
}

 
 

In contrast, this matches the criteria at the if, falling into the first conditional:

try {
   throw Error('Can you see this?');
}
catch(error){
   if (error.message){
      this.loggingContract.Log(error.message);
   } else {
      this.loggingContract.Log(error);
   }
}

 
 

In both cases I am trying to boil the error down to a string.

Use the checked attribute at a checkbox in an Angular 7 application.

<input type="checkbox" (click)="updateFoo(foo)" [checked]="foo.isCool">

How to wall off services behind lazy-loading in an Angular 7 application.

The trick I elude to here, in the name of maintainability is done by having routes for every item at the main menu system, beyond an innocuous and innocent static home page which is just a landing page with some text that never changes, like so:

{ path: 'foo', loadChildren: './modules/foo.module#FooModule' },

 
 

The above would go in the main routing module which supports the outermost God module for the application. Then there would be a modules folder somewhere with two different modules for each route in the menu system, one being the main module which would load the services for external dependencies and the other being its sister routing module which might look like so:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { FooComponent } from '../components/foo.component';
import { FooAuthenticatedComponent } from '../components/foo-authenticated.component';
import { FooUnauthorizedComponent } from '../components/foo-unauthorized.component';
import { FooGuard } from '../guards/foo.guard';
const routes: Routes = [
   { path: '', component: FooComponent },
   { path: 'authenticated', component: FooAuthenticatedComponent, canActivate: [FooGuard] },
   { path: 'unauthorized', component: FooUnauthorizedComponent }
];
@NgModule({
   imports: [RouterModule.forChild(routes)],
   exports: [RouterModule],
   providers: [FooGuard]
})
export class FooRoutingModule { }

 
 

FooComponent would just look like this, attempting a redirect to FooAuthenticatedComponent and instead redirecting to FooUnauthorizedComponent if the FooGuard determined that the user should not go forward.

import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
   selector: 'foo',
   template: 'Authenticating...'
})
export class FooComponent {
   constructor(router: Router) {
      router.navigate(['/foo','authenticated']);
   }
}

 
 

FooGuard could look like:

import { Injectable, Injector } from '@angular/core';
import { ActiveDirectoryContract } from '../contracts/active-directory.contract';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { User } from '../models/user.model';
import { Role } from '../models/role.enum';
@Injectable()
export class FooGuard implements CanActivate {
   private activeDirectoryContract:ActiveDirectoryContract;
   private router: Router;
   
   constructor(public injector: Injector, public router: Router){
      this.activeDirectoryContract = injector.get(ActiveDirectoryContract);
      this.router = injector.get(Router);
   }
   
   canActivate(route: ActivatedRouteSnapshot): boolean {
      let user:User = this.activeDirectoryContract.GetUser(false);
      if (user.Role != Role.Yin && user.Role != Role.Yang) {
         this.router.navigate(['/foo','unauthorized']);
      }
      return true;
   }
}

ConvertFrom-Json cmdlet

Pronounced command-let, a cmdlet is a PowerShell script. ConvertFrom-Json casts JSON to a PSCustomObject object and thus it is to PowerShell what Newtonsoft is to C# in some regards.

Wednesday, March 6, 2019

BOM stands for byte order mark.

Endianness is a term for the order of bytes and text can start with an optional BOM marker to signify which variety of endianness is in use. Variants "big Indian" and "little Indian" are really big endian and little endian and not as politically incorrect as they sound.

blue-green deployments

This is a trick in deploying to production in which the changes are first rolled out to one of two servers or half of a set of servers and then, only after that is done, the changes are rolled out to the other half of things. This allows for production to never be down as the half not being worked on catches traffic while the half being worked on is down.

Akka.NET and the Actor Model?

I see in my email a teaser for a tech talk on this back in Houston, but, of course, I don't live in Texas anymore. Built on something called Petabridge, Akka.NET is a framework for an event-driven application that accounts for concurrency concerns. Actor comes from a 1973 paper by a Carl Hewitt and might be the events, the acts, in this thing.

Tuesday, March 5, 2019

Use Dapper to map to an object what comes back from a stored procedure assuming the property names are identical.

Go to: Tools > NuGet Package Manager > Manage NuGet Packages for Solution... ...in Visual Studio Preview 2019. Then click the "Browse" tab and search for "Dapper" to install the Dapper microORM at your application. Use it like so in C#:

using MyThing.Core.ExternalDependencies.Repositories;
using MyThing.Core.Objects;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using Dapper;
namespace MyThing.Infrastructure.ExternalDependencies.Repositories
{
   public class FooRepository : IFooRepository
   {
      public IEnumerable<Foo> GetFoos(string connectionString)
      {
         using (IDbConnection db = new SqlConnection(connectionString))
         {
            return db.Query<Foo>("EXEC myStoredProcedure");
         }
      }
   }
}

When your Jasmine/Karma tests run forever in an endless loop without ever finishing in an Azure DevOps pipeline...

...Well, maybe they do this in "real life" too. Open karma.conf.js in the root of your application and change singleRun: false to singleRun: true

Monday, March 4, 2019

You must explicitly loop in System.Linq in a using declaration to do a .ToList() on an IEnumerable in C#.

JetBrains ReSharper is letting me down at the Visual Studio 2019 Preview. Perhaps it is because I am running the IDE as a different user (Administrator) from the one that installed ReSharper.

member names cannot be the same as their enclosing type

This is a thing in a .NET Core #C application. A class named Foo cannot have a getsetter inside of it named Foo. Boo!

Sunday, March 3, 2019

At JavaScript MN on Wednesday night, I saw Mike Emo speak on React Native!

React Native (rn) is not an Expo app. An Expo app is a React application running in a browser without controls that looks like a native application, exactly the same trick Capacitor uses in an Ionic 4 application. So if React Native is not running in a browser, how can JavaScript possibility be running at your phone? JavaScriptCore (JSC) is an engine running at both Android and iPhone devices. This engine is used instead of a browser and in its approach a JavaScript thread running in a loop at its main thread can kick off other things. This is, to my understanding, the same trick that lets Node run as a server. Anyhow, the JSC thread can communicate with threads of native code at both Android and iPhone devices and these in turn can instantiate some UI elements. Having said that it probably won't surprise you to learn that Mike Emo suggests that React Native is buggy. He suggests that it is less painful to spin up two separate Cocoa/Objective-C and Java code bases to accommodate iPhone and Android respectively independently than it is to author in React Native. The debugger on a particular Android app is of a different engine. It's not the JSC and that leaves you working blind in some cases. You use XCode to work on React Native on a Mac and you deploy to Google Store or wherever. CRNA (Create React Native App) is perhaps pronounced "cree-nuh" and is a command line tool. HockeyApp seems to be a deployment tool. "React Navigation" is apparently a pretty good component for routing in any React application. There are a lot of pseudo HTML tags which start out with <View in React Native apps. The marquee HTML tag was mentioned by someone before the meeting got rolling. It is a tag for a horizontally scrolling stock ticker effect. I mention the marquee tag because there was more at this event than just Mike. There were three lightning talks. In one of them Shalanah Dawson showed off three different user interfaces she had built. A guy who called himself just "Lemon" had a lightning talk on progressive web apps suggesting that all PWAs have an HTTPS connection, a manifest.json, and a service-worker.js. He likes Let's Encrypt as an eighty-dollar-a-year SSL (secure socket layer) service. PWABuilder by Microsoft was suggested to be the easiest way to get started. Give it a URL and it will create a manifest.json and a service-worker.js for you. Service Workies is another tool. serviceworke.rs by Mozilla has recipes on things like how to Web Push and staggered caching. PWA Fire was online helper number four. A guy named Simon (perhaps a Simon Kinsler???) gave a lightning talk on https://webtask.io/make which will allow you to make simple web sites with up to five hundred kilobytes of hosting for simple text for free at its storage API. In the photo here Simon is in the center with Lemon at the left and Brandon Johnson, the moderator who seems to be head of state of JavaScript MN, at the right.

Saturday, March 2, 2019

I saw Joe DeCock of ILM Services speak on TypeScript at the Twin Cities .NET User Group on Thursday night which is also hosted at ILM Services.

Did I mention that I work at ILM Services too? Anyhow, the talk had to do with some of the hoops the language has to jump through to introduce comparable to C#, compiler-safe capabilities to its subset of JavaScript. Arrays look like this under the hood:

interface Array<T> {
   length: number;
   
//lots of other methods here
   reverse(): T[];
   [n: number]: T;
}

 
 

[n: number] has a sister [s: string] which can be used to fish stuff out of a dictionary. Indeed, Lodash's dictionary works in this manner in TypeScript. The Index Type Query Operator uses the keyof keyword in tandem with the extends keyword like so:

get<T, Key extends keyof T> (
   object: T,
   path: Key
): T[Key];

 
 

Use this stuff like so:

get(someComplexObject, 'someProperty');

 
 

This will fish out a property from an object in another dictionaryesque trick. Joe DeCock spent some time explaining how extends and extends keyof are similar and different with a Venn diagram at one of his slides. This is inheritance and if you inherit from T with extends in classic inheritance or if you inherit from T with extends keyof, in both cases you are making a type that is a more-specific version of T. What is different is that while extends is going to allow you to add properties to your more-specific T and make it fatter, extends keyof subtracts stuff, reducing T to just what you want from it. In the example immediately above we are reducing T to its someProperty property. A good chunk of the talk went into TypeScript's very-different-from-C# flavor of method overloading. The only way this can work is by handing in a union type and then having different workflows inside of a method or other function based on what was handed in. (There will be precious little you can do with a union type without breaking back out what it is specifically beyond .toString() and .valueOf() after all.) Alright, so if you really wanted two methods named the same thing wherein one took a Date and one took a string and you are settling for handing in to a single method a Date | string, how can you make a distinction when you need it? There are really two ways to do this and one is better than the other.

  1. if ((<Date>myBirthday).getFullYear) { is a compiler-safe way to see if you may call .getFullYear() on the thing you handed in, but perhaps a better way to go is...
  2. if (myBirthday instanceof Date) {
    This is an example of "narrowing" with the instanceof keyword which may be used with types. Narrowing with a primative such as a string uses the typeof keyword like so in contrast:
    if (typeof myBirthday === 'string') {

What if we don't just want to hand in different things, but we also want the return type to vary based upon what we hand in? Well, we probably don't want to just return a union type in those scenarios as it is inconvenient. Every time we used our method we would have to write some logic like what is above to make sense of what it returned after all. That's not user-friendly at all. The solution is to use a User Defined Type Guard or two or three like so:

function identity(x:string): string;
function identity(x:number): number;
function identity(x: string | number): string | number {
   return x;
}

 
 

The more complicated your TypeScript gets the more it leads to unintelligible errors. When you find yourself in these scenarios, progressively walk your code downwards to a dumber and dumber more simplistic crafting until the error messages make sense.

When a problem seems to lie at an interface in C#, temporarily removing the interface can help in troubleshooting.

I was getting this today:

The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

 
 

I was calling a method at an interface that returned Task and the method at a class that was wired up to it started out with public async Task, so it seemed like it should work. I was using the await keyword where I called out the method and herein I got the squiggly red line under my line of code in Visual Studio 2019. It turned that out the method wrapping the call did not have the async keyword decorating it and I could not see this until I attempted to directly call the class the interface buffered away.

an example of a transaction around a data context in Entity Framework 6's code first way of doing things

using (var transaction = _myContext.BeginTransaction()) {
   try {
      cheese.type = type;
      cheese.percentage = 100;
      await UpdateCheese(foo);
      tacos[0] = await AssociateCheeseToTacos(foo);
      transaction.Commit();
   }
   catch (Exception ex) {
      transaction.Rollback();
      throw ex;
   }
}

Perhaps a way to new up (instantiate) a Task in C#???

return new Task<bool>(() => false);

Friday, March 1, 2019

"Full Page Screen Capture" is imperfect, but perhaps good enough too

At https://chrome.google.com/webstore/ one may search for "screen capture" to find "Full Page Screen Capture" which is a plugin in that will screen capture Google Chrome while also scrolling down the scrollbar to get everything and not just what you immediately see. You press Alt-Shift-P to make it go. It doesn't lose anything, but you will notice some choppiness where is struggled to scroll the scrollbar, etc.

Did you know you may nest a .gitignore any number of folders deep in the git paradigm?

What is inside could look like this:

/.vs
Foo.sln.DotSettings.user
/Foo.Core/bin
/Foo.Core/obj
/Foo.Core.Test/bin
/Foo.Core.Test/obj
/Foo.Infrastructure/bin
/Foo.Infrastructure/obj
/Foo.RestApi/bin
/Foo.RestApi/obj

float: none;

In CSS this means that the element does not float. This could just be left off in most cases. When I saw it I wondered what it was to tell you the truth. It rears its head on page 291 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis. This suggests initial and inherit are other settings for this beyond right and left, and initial seems a lot like none to me.