Tuesday, December 31, 2019

Copy HTML into the clipboard from the DOM with JavaScript.

var textArea = document.createElement("textarea");
textArea.value = document.getElementById("touchMe").innerHTML;
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);

 
 

Honestly, something like this might be a little bit better:

if (!copying) {
   copying = true;
   var textArea = document.createElement("textarea");
   textArea.value = document.getElementById("touchMe").innerHTML;
   textArea.style.position = "fixed";
   document.body.appendChild(textArea);
   textArea.focus();
   textArea.select();
   document.execCommand('copy');
   var cleanUp = function() {
   try {
      document.body.removeChild(textArea);
   } catch (error) {
      
   }    clearInterval(interval);
   copying = false;
   };
   var interval = setInterval(cleanUp, 6000);
}

A switch is designed to connect computers within your LAN.

A router gives you your internet connection.

Ctrl-P

...tends to kick off printing things in Windowsland.

SentryOne Plan Explorer

This helps you see the execution plan for a blob of T-SQL and tune it.

Apache Directory Studio

It will allow you to browse Active Directory records.

ApexSQL

It is a set of SQL Server DBA tools.

pivot table

It's a snapshot, a high-level summary of a more detailed table.

Dashforge

It's a Bootstrap 4 template for a dashboard.

New Local Branch From...

The "Team Explorer" in Visual Studio 2019 will allow you to tie into Git. You may switch between the dev and master branches. You may right-click on one of them and pick "New Local Branch From..." to make a new branch.

GitLab is Linux-based.

You host it on Linux servers. You do Azure DevOps stuff with it. You can have a wiki.

bitmask

This determines something with a series of on and off switches.

Koycera is a brand of printer.

Lexmark is a brand of printer.

Luddite

dictionary.com offers: someone who is opposed or resistant to new technologies or technological change

Scala cake pattern

It has to do with stacking up components to build out an application.

switcheroo

It swaps out a React component in a React app based upon part of the URL, hence the name switcheroo. It is JavaScript routing magic to accommodate partial views in asynchronous swapability, etc.

Scalar functions in T-SQL return you a single value while table-valued functions return a table.

Table-valued functions (TVF) are kind of like views only you hand in some variables. In aggregate functions you write your own versions of some of the "aggregates" associated with GROUP BY clauses such as SUM and COUNT and STRING_AGG. Meh.

Mitel Connect

It is another stupid chat app.

Monday, December 30, 2019

It is possible to craft raw SQL strings with Entity Framework implementations that just allow attackers to do SQL injection attacks!

using System;
using System.Collections.Generic;
using System.Linq;
using DataAccessLayer.Models;
using Microsoft.EntityFrameworkCore;
namespace DataAccessLayer.Filters.Entity
{
   public static partial class Filters
   {
      public static List<dbo.Foo> GetFoo(this DbSet<Foo> DbSet, string bar) =>
         DbSet.FromSqlRaw("select * from Foo where Baz = '{0}'", bar)
            .Include(x => x.Qux)
            .OrderBy(x => x.Id)
            .ToList();
   }
}

 
 

The .Include here will drag along the joined Qux for each Foo if there is one I think.

Umbrella JS

It is something like jQuery with similar syntax only lighter in fatness. This is not just a lighter jQuery like zepto.js was.

Saturday, December 28, 2019

Winaero is pronounced "win arrow" and may be installed at the most recent three versions of Windows to extend what Windows may do.

For example, you may turn off the ability to lock your computer at Windows 10 with Winaero.

Premium domain names sort of cost more.

I read about them this morning and there are basically two shapes. The keepers of .info or other new-as-of-the-new-millennium top level domains can subjectively price up never registered names they think are special. The other, more interesting shape is simply a domain name that someone already owns having a fat price tag. This squatter-controlled variant is interesting to me because I just realized this week that its shape has changed a little bit. It used to be that when you went to register.com or Network Solutions or GoDaddy or wherever to try to buy decanet.com that you would just be told that someone already owns it and then you could use the whois lookup stuff to figure out who owned it. Also, you might be able to just go to decanet.com and see a ceremonial web page advertising for how one might buy the domain name. Anyhow, the ceremonial web page is still there, but the registry stuff behaves differently. Instead of being told at the registry that "it's taken" you are told "it's available" and when you hit their shopping cart to try to checkout your socks are blown off (forgive the cliché (who came up with "socks are blown off" anyways?)) by the price tag. How is that possible? Apparently there are now tools that facilitate this for domain name squatters that registries honor. Arguably this is just greasing the wheels of capitalism. It probably helps average Joe by just dropping the price tag to an acceptable floor in lieu of there being some bidding and negotiations back-and-forth.

Paywall

It's the whole selective access restriction that does not allow you to see content at a web site until you sign up for a membership. You have to pay to get around the wall, get it? I found a playlist with the first few episodes of the Harley Quinn cartoon at YouTube and this term was namedropped along the way.

Friday, December 27, 2019

createStore

It's the command to actually create the Redux store in Reactland. And, yes, you don't have to do this in the Angular approach.

Dragging in D3 charting to an Angular application allows for some jQueryesque nastiness.

Import like so:

import * as d3 from 'd3';

 
 

Make a variable:

private host: d3.Selection<any>;

 
 

Then do stuff:

let innerWrapper = this.host.select("#outerWrapper")
   .append("div")
   .attr("id", "innerWrapper")
   .style("max-width", '800px');

The feature name "records" does not exist in the state, therefore createFeatureSelector cannot access it.

This error came for me in having an store shaped like so:

import { IModelStore } from "../models/model-store";
export interface IMainStore {
   records: IModelStore
}
export const ModelStore: IModelStore = {
   records: null
}

 
 

I replaced it with this:

import { IModelStore } from "../models/model-store";
export interface IMainStore {
   models: IModelStore
}
export const ModelStore: IModelStore = {
   records: null
}

 
 

The doubleup of the name "records" was somehow making things sick!

No store found. Make sure you follow the instructions.

When you see this error in the Redux DevTools for Google Chrome (which appear as a new tab in the Google Chrome Developer Tools that you see when you press F12 at Google Chrome) you get around that by putting this as an import at your outermost God module of your Angular 8 application:

StoreDevtoolsModule.instrument()

 
 

Put this up top in the .ts file to get it to work:

import { StoreDevtoolsModule } from '@ngrx/store-devtools';

 
 

In order to get that to work you must specifically install something.

npm install @ngrx/store-devtools

What's cooking in the kitchen?

I've learned the hard way that the jury is out as to whether or not a job is a good job until the day it ends. Today was my last day at ILM Services and I am pleased to report that it was a good job. Let me introduce you to some of the characters:

Dan Lehto is in the foreground of this 1/14/2019 photo and from left to right across the back are Jason "J" Erdahl, Jason Carlson, Matt McDonald, Luna Ahmed, and finally Amy Rempher with her back to us. We were celebrating five years of employment for Matt on this day.

Let's just focus on the faces showing in this photo. From left to right they are Alex Ryazhnov, Phil Nowak, Amy Rempher, Doug Little, and Brett Hazen. The photo is from 7/26/2019 and the occasion was a planning session for what the sessions should be for the 2019 Minnesota Developers Conference which was spearheaded by ILM (imagination, learning, mentorship).

Amy Rempher, Joe DeCock, Phil Nowak with his back to us, Dan Lehto, Chris Vitko, Justin Blake, and finally Matt McDonald are shown from left to right in this 11/22/2019 meeting for which there was both a Thanksgiving time potluck and later a discourse on 401K benefits that I didn't stick around for. Matt is hamming up the picture a little bit by being the one person in all three photos who realizes he is being photographed, but I forgive him.

Tuesday, December 24, 2019

I'm finally done with Chapter 8 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis.

There are now less than one hundred pages for me to read in 2020 to be done with this book I am completely sick of. By the time I am done with this thing I will have been nibbling on it for more than two years. I guess this shows off how quickly I read books. I remember that when I was at Headspring that Dustin Wells would opine that he never finished books so I probably shouldn't judge myself too harshly. He's doing just fine. Anyways, here are some of the things I've learned since last writing of this treatise on now dated tech.

  1. Some claims in the Microsoft Identity model are spun up on page 391. I don't understand this yet. now is a variable below which has DateTime.UtcNow assigned to it.
    var claims = new[] {
       new Claim(JwtRegisteredClaimNames.Sub, user.Id),
       new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
       new Claim(JwtRegisteredClaimNames.Iat,
          new DateTimeOffset(now).ToUnixTimeSeconds().ToString())
    };
  2. The book has us storing tokens in localStorage! I don't know how I feel about that. Anyhow it mentions that roundtripping (making up my own word) to localStorage and back is a synchronous thing and if you need to do it asynchronously to improve performance you should check out angular-async-local-storage an npm package by Cyrille Tuzi namedropped on page 400.
  3. ?. the Elvis operator of Angular 5 should not be confused with !. the "non-null assertion operator" of TypeScript which is used in the middle of something in a truthy/falsey check. If the left side is both not null and not undefined and the right side is truthy the two things separated by the operator (the right thing should be a property/variable or a function/method hanging off of the left thing as would make sense if the exclamation point were not there) get graded as truthy. This comes up twice in chapter 8. I don't understand how it works other than as perhaps a convention. If you look at the JavaScript the Typescript makes the exclamation point just comes out so there is no safeguard keeping your code from blowing up when the left side is null or undefined.
  4. The book advocates using the Watch window in Visual Studio to look at the Request coming over the wire to the API side and at Request.Headers.HeaderAuthorization you may see the token.
  5. The way the ahead of time complication works apparently involves turning a template into a TypeScript class. This is the reason that the component's methods accessed by the template must be public in AOT complication as now a class is trying to talk to a different class in TypeScript compilation. Without AOT, the template may just access private methods in a paradigm that at first blew my mind as it broke with the web forms and web forms code behinds way of doing things. (Angular is the new web forms.)
  6. The [Authorize] attribute in ASP.NET Core decorates API endpoints to validate the token used. I don't understand how this thing works yet either.
  7. Sliding sessions allow more life to be added to a token, setting back its expiration date, with every use of the token. So if a token is to only live for half an hour and you spend four solid hours working in a web portal, you will not be booted.

Saturday, December 21, 2019

HTTP referer

I just saw something online that points out that this field in an HTTP header (for where one was before one came in the door to where they are now) is a misspelling of referrer.

Friday, December 20, 2019

How do I test a service in an Angular application?

What a puzzle! I have found an article online that just shows off testing services that are the equivalent of static utilities in C#, but where is the fun in that? The really question here is: How do I test a service that has external dependencies (API calls) in it? I think you are going to have to do the deps trick to hand in external dependencies to a service, stub/mock the deps, and then unit test the rest of functionality in the service. This would mean that HttpClient calls are kept in a few common methods and that services just prep what is handed into those methods, etc. This may sound clunky, but it is less clunky if you are doing GraphQL instead of ReST wherein you are always using the POST verb and what is handed in, the query, is always ultimately a string.

  1. https://semaphoreci.com/community/tutorials/testing-services-in-angular-2
  2. https://medium.com/@MatheusCAS/injecting-a-service-into-another-service-in-angular-3b253df5c21
  3. https://blog.angulartraining.com/how-to-write-unit-tests-for-angular-code-that-uses-the-httpclient-429fa782eb15

Get back both an Observable and then later ultimately a Promise with HttpClient in an Angular 8 application.

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { Model } from '../models/model';
import { HttpClient } from '@angular/common/http';
import { Contract } from '../contracts/contract';
@Injectable()
export class Service implements Contract {
   constructor(private http: HttpClient) {}
   
   GetModelsFromServer(methodToCall: (models:Array<Model>) => void): void {
      let o:Observable<Array<Model>> = this.http.get<Array<Model>>(environment.x);
      let p:Promise<Array<Model>> = o.toPromise();
      p.then((results) => {
            console.log(results);
         methodToCall(results);
         }, (error) => {
            console.log("Trouble: " + JSON.stringify(error));
         });
   }
}

 
 

I have long heard that HttpClient was the new Http and what is above should keep you from using this anymore:

import { Http, Headers, RequestOptions } from '@angular/http';

 
 

Posts look like this instead:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { Model } from '../models/model';
import { HttpClient } from '@angular/common/http';
import { Contract } from '../contracts/contract';
import { HttpHeaders } from '@angular/common/http';
@Injectable()
export class Service implements Contract {
   constructor(private http: HttpClient) {}
   
   SaveToServer(model: Model, methodToCall: (models:Model) => void): void {
      let o:Observable<Model> = this.http.post<Model>(
            environment.x,
            model,
            {
               headers: new HttpHeaders({'Content-Type': 'application/json'})
            }
         );
      let p:Promise<Model> = o.toPromise();
      p.then((results) => {
         console.log(results);
         methodToCall(results);
         }, (error) => {
         console.log("Trouble: " + JSON.stringify(error));
         });
   }
}

 
 

Puts look like this:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { Model } from '../models/model';
import { HttpClient } from '@angular/common/http';
import { Contract } from '../contracts/contract';
import { HttpHeaders } from '@angular/common/http';
@Injectable()
export class Service implements Contract {
   constructor(private http: HttpClient) {}
   
   UpdateModel(model: Model): void {
      let o:Observable<void> = this.http.put<void>(
            environment.x,
            model,
            {
               headers: new HttpHeaders({'Content-Type': 'application/json'})
            }
         );
      let p:Promise<void> = o.toPromise();
      p.then(() => {
            console.log("Fire and forget without error!");
         }, (error) => {
            console.log("Trouble: " + JSON.stringify(error));
         });
   }
}

 
 

Delete:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { HttpClient } from '@angular/common/http';
import { Contract } from '../contracts/contract';
import { HttpHeaders } from '@angular/common/http';
@Injectable()
export class Service implements Contract {
   constructor(private http: HttpClient) {}
   
   DeleteModel(id: number): void {
      let o:Observable<void> = this.http.delete<void>(
            environment.x + "/" + id,
            {
               headers: new HttpHeaders({'Content-Type': 'application/json'})
            }
         );
      let p:Promise<void> = o.toPromise();
      p.then(() => {
            console.log("Fire and forget without error!");
         }, (error) => {
            console.log("Trouble: " + JSON.stringify(error));
         });
   }
}

Thursday, December 19, 2019

When I spun up an Angular 8 application today and tried to add providers to AppModule a series of errors appeared at the console requiring doctor-ups to polyfills.ts as a remedy.

Uncaught ReferenceError: global is not defined

To get past this first, I added this to polyfills.ts at the top:

(window as any).global = window;

 
 

Uncaught ReferenceError: Buffer is not defined

To get past this next, I expanded upon what I put in polyfills.ts like so:

(window as any).global = window;
(window as any).Buffer = {};

 
 

Uncaught ReferenceError: process is not defined

To get past this third in order and second to last, I expanded upon what I put in polyfills.ts like so:

(window as any).global = window;
(window as any).Buffer = {};
(window as any).process = {
   env: { DEBUG: undefined }
};

 
 

Uncaught TypeError: Cannot read property 'slice' of undefined

To get past this lastly, I expanded upon what I put in polyfills.ts like so:

(window as any).global = window;
(window as any).Buffer = {};
(window as any).process = {
   env: { DEBUG: undefined },
   version: []
};

a different way to do the Injectable decorator at a service in an Angular 8 application which cries out the module to wire it up

@Injectable({
   providedIn: AppModule
})

command line commands to set up a new Angular 8 application with Materials and "the store"

  • npm install -g @angular/cli
  • npm install
  • ng new dumbapp --routing --style=scss
  • cd dumbapp
  • ng add @angular/material
  • npm install @ngrx/store @ngrx/effects

'ng' is not recognized as an internal or external command, operable program or batch file

Try installing the Angular CLI globally with the -g per line two here. That should get you around this error. I found something in Googling about a PATH variable. (I started to type "advanced system settings" at the start bar in Windowsland and that opened up a "View advanced system settings" option which I clicked which opened the "System Properties" dialog box. There I clicked the "Environment Variables..." button to open the "Environment Variables" dialog box.) Anyhow, it's not the PATH variable.

Make a dumb .NET Framework 4.7.2 API to test an Angular application with in Visual Studio 2017!

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
namespace DumbApi.Controllers
{
   public class ValuesController : ApiController
   {
      public HttpResponseMessage Get()
      {
         DateTime immediacy = DateTime.UtcNow;
         List<Tuple<string, int>> tuples = new List<Tuple<string, int>>()
         {
            new Tuple<string, int>("foo", immediacy.Day),
            new Tuple<string, int>("bar", immediacy.Hour),
            new Tuple<string, int>("baz", immediacy.Minute),
            new Tuple<string, int>("qux", immediacy.Second)
         };
         HttpConfiguration config = new HttpConfiguration();
         config.Formatters.JsonFormatter.SupportedMediaTypes.Add(
            new MediaTypeHeaderValue("text/html")
         );
         var response = Request.CreateResponse(HttpStatusCode.OK, tuples, config);
         response.Headers.Add("Access-Control-Allow-Origin", "*");
         return response;
      }
   }
}

 
 

What is above will spit out something like this:

[
   {"m_Item1":"foo","m_Item2":19},
   {"m_Item1":"bar","m_Item2":15},
   {"m_Item1":"baz","m_Item2":32},
   {"m_Item1":"qux","m_Item2":16}
]

Wednesday, December 18, 2019

How may I check spelling in Visual Studio?

Maybe with... Visual Studio Spell Checker ...well maybe not. A friend is telling me it doesn't work well with Visual Studio 2019. Nuts. Other links:

SnapCard can mean two different things.

It can be a card you swipe to spend Bitcoin or it can be a card for spending food stamps in modern times. In the second circumstance SNAP is the Supplemental Nutrition Assistance Program.

Tuesday, December 17, 2019

Sunday, December 15, 2019

.NET 5

Xamarin, Mono, .NET Core, and .NET Framework are all going to be unified in this fifth thing and it will be built out in a way that they may all be built out.

Thursday, December 12, 2019

looking for a used car?

  • https://www.kbb.com/ can help with reasonable pricing if you punch in the year, make, model, and mileage. The corporate entity name, such as Toyota, is the make. The particular type car, such as Corolla, is the model.
  • https://www.carfax.com/value/ can help with the history of a car if you punch in the VIN (vehicle identification number) number.

the "teach a man to fish" quote that often comes up in software

Give a man a fish, and you feed him for a day. Teach a man to fish, and you feed him for a lifetime.

Pitney Bowes

...peddles the personal postage meter.

Wednesday, December 11, 2019

assorted strange SQL

  1. LEAD and LAG are esoteric and obscure. They are like ROW_NUMBER() only they get either the page before or the page after what ROW_NUMBER() would get.
  2. The whole SELECT INTO trick in T-SQL to SELECT into a temp table that is spun up right then may also be used to just make a new, regular table!
  3. When a table variable is passed to a stored procedure (in T-SQL) it is a TVP (table-valued parameter).
  4. CTEs in T-SQL use In-Memory memory management while table variables may use the Memory-Optimized Table approach to memory. I don't really understand this stuff. The MOT approach has a divide between Durable and Non-Durable and I don't understand that yet either.
  5. Not every reserved keyword in T-SQL must be wrapped in brackets to be used as a name. This only applies to the keywords which could otherwise be keywords (without error) in the SQL statement at hand.

Sage

This is another ERP yet. Sage is French and you pay upfront for everything you are going to get in terms of goodies instead of as you go.

Tuesday, December 10, 2019

when the file you added is not under "Excluded Changes" in TFS for some strange reason

  1. Go into the Source Control Explorer in Visual Studio 2017.
  2. Navigate to the folder holding the file you want to add.
  3. Right-click and pick: Add Items to Folder...

You may cast numbers back to characters in C#.

Obviously you may do something like so to get the number 120.

char x = 'x';
int number = (int)x;

 
 

I would offer that this is also legit for getting \r

char enter = (char)13;

Monday, December 9, 2019

ENOENT stands for Error NO ENTry

The file may just be in some dumb locked state when you get the ENOENT error. Try stopping and restarting the server. I fixed this problem for myself with as much today.

TypeScript let keyword block scoping coolness in switch statements

One of the things the let scoping around if/then statement affords is that you may use a let variable with the same name in different cases of a case/switch statement if you just nest that variable's instantiation each time inside of a truthy/false check in an if statement.

the .find in lodash

My match variable here ended up being a single object and not an array of objects.

let match = _.find(this.attorneyFilterList, function(item) {
   return item.label == potentialState.openingTier;
});

Sunday, December 8, 2019

I'd like to tell you about my three predictions for the 2020s.

  1. The ever escalating upwards trend in censorship (restrictions on what is acceptable on social media) hits a plateau and a consensus that we begrudgingly accept as a society governs us. This lasts as a guideline across a long lull until it is challenged again and when it is challenged again it will not be quickly tossed out.
  2. The near monopoly on tech that the United States of America enjoys will end as other nations get into the game.
  3. JavaScript loses its newness.

 
 

Addendum 12/10/2019: In the video clip here I meant Knockout when I said Bootstrap. Ha! I was distracted.

 
 

Addendum 1/30/2020: My reference to Bootstrap here is not ridiculous after all. I looked into it and Bootstrap, which has a good deal of JavaScript to it, basically is a Mickey Mouse GitHub project.

Here are some random things I've never heard about before from a ping over LinkedIn to get me to pursue a certification.

Six Sigma is a spec for improving a process. Define, Measure, Analyze, Improve, and Control are the five steps in the six, which doesn't make sense. Also, it might be Define, Measure, Analyze, Design, and Verify too. I'm just glancing at the Wikipedia write up and I don't really care. TOGAF is The Open Group Architecture Framework and there is a certification you can get along these lines. I guess there are a handful of different certifications in different technical oddities.

Saturday, December 7, 2019

little o or small o

The difference between this and Big O is that Big O has to do with exponential complexity, the same list to loop through potentially having to be looped against for every step in an outer loop, etc. The "find the longest palindrome" example would apply to Big O. In little o the inner loop is just a different thing altogether with its size not bound to the size of the first loop to being with. An example might be one in which we have two lists of words and we want to make a third list that only has words in both the lists, perhaps to give bonus offers to customers (usernames for the words) enrolled in two separate loyalty programs or some such hogwash. Also, you can see the right way and the wrong way to this, right? The wrong way makes for easy to read code but is expensive. You could just have a loop across the first list with a loop inside for the second list creating an a times b level of expensive/complexity. The better thing to do is to sort both lists alphabetically and then increment a position in the second list appropriately as you walk the first list and therein just walk the second list once. Also, Big O measures the most expensive possible circumstance while big Ω the least and big ϴ both, and I thought I'd mention it with everything else here. The upper bounds and the lower bounds are the proper terms for what I am dubbing "most" and "least" respectively.

You may have a database index that is made up of two columns wherein the combo of the two columns must be unique.

It is a thing.

Friday, December 6, 2019

ExpressionChangedAfterItHasBeenCheckedError

This suggests this is specifically to do with a ViewChild getting messed up in the AfterViewInit lifecycle hook in an Angular application. It is going to be something like this insofar as you are trying to manipulate a ViewChild that is lacking in some fashion. The first link I provide here suggests it stems from race conditions as many things manipulate the DOM at "once" so to speak.

Thursday, December 5, 2019

the quickest way to make a copy of an array with a new pointer in JavaScript

foo = foo.slice();

 
 

This is obviously different from the way to approach an object like so:

foo = Object.assign({}, foo);

 
 

In TypeScript you would approach the object issue like so:

foo = { ...foo };

 
 

What is the difference between .splice() and .slice() in JavaScript? They both return a chunk of the array, but the slice leaves the original unedited while the splice will remove from the first array the part it hands back from its returning.

Tux is the penguin mascot of Linux.

Puffy is the pufferfish mascot of OpenBSD and Beastie is the demon mascot of FreeBSD.

the creative

This is another word for the mockups or the comps. It's not wireframes. It is stuff with the full Photoshop bake out of how screens should look. One should be able to roll HTML and CSS based on the creative.

Razor in .NET Core

  1. Fluent Validation a library for form validations.
  2. The plain Jane validations in .NET Core's MVC and Razor paradigm are more spiffy than those of the .NET Framework days. Validations can happen at a POST method at a ReST API controller action based on the data annotations at the POCO getting mapped to.
  3. jQuery DataTables is a way to do a paginated list of records and it does support a way to do server-side pagination with AJAX calls.

Tuesday, December 3, 2019

How do I get at someone else's Shelveset in TFS.

Go to your own shelvesets and you will see, at the top of the pane, a place to change the name of party for the shelvesets list.

using statements in C# 8 have a bit more variations

using FileStream f = new FileStream(@"C:\users\jaredpar\using.md");

Per this cheatsheet is legit, and you can just use f and eventually f will dispose. The f lives until the close curly brace around it.

the Subject generic in the TypeScript of RxJS

As suggested here it is an Observable. Just put the next thing onto it with .next as suggested here.

When you somehow highlight a row of code in Visual Studio Code...

Well, for me this happened when I pressed Ctrl-F and opened a little search bar and then the copy in the search was highlighted in the file I was looking at. I got rid of it by closing the search bar.

get to "Manage Connections" in TFS when your TFS in the cloud seems to be offline

I cannot seem to duplicate the error I had to be sure I am typing up the right thing in this blog posting, but what I think I did was go to the Team Explorer pane in Visual Studio 2017, then click the downwards pointing arrow at the right of Home at the left top, and then I either picked it here/there or I picked Settings or something first.

Monday, December 2, 2019

OnPreLoad

In web forms this event runs before Page_Load and has to do with a point in time when ViewState is loaded but not the controls just yet. I had not heard of it before. This has a cheatsheet of lifecycle stuff for web forms.

Sunday, December 1, 2019

sfs stands for shout out for shoutout

If you are advertising this on Instagram you are saying: holla at me and I'll holla back... we can both advertise each other on Instagram and gain followers from each other's followers! (fine.)

second stab at React

Alright guys, React is now the thing for me to learn and I have gone back through the first twenty minutes of this for a second time as a refresher. Beyond what I wrote here, the following is stuff I did not document the first time.

  1. Install the latest Node and also React Developer Tools for Chrome before starting a new app. With regards to this second item, two new tabs will appear in the Google Chrome Developer Tools when you press F12, Components and Profiler, but they will only appear when you are looking at a React application.
  2. I used the three steps here to make a new application and get it underway. I want to say that I learned that in the first step the name of the application cannot just be a period as the YouTube movie suggests and it cannot have an uppercase letter in it. I think both of these things were once viable. They are not viable anymore.
  3. The Virtual DOM in React allows for isolation, so that when a form posts to a "Post Component" only the component changes and not the whole of the page.
  4. The context API allows for the use of "app-level state" without Redux.
  5. Class Post extends React.Component is an example of the declaration for a component. I am pretty sure this (well, something very much like it) exists elsewhere on this blog but here it is again.
  6. Ctrl-C will stop the server when run from a command prompt in Windowsland the same as in the Angular space.
  7. render() is a lifecycle method on a component and the only one it has to have.

Thursday, November 28, 2019

I guess the query part of a query handed into GraphQL has two parts.

As seen here, the first chuck of the query which looks like a method seems to spec out the query being called by name as suggested before the opening parenthesis and then the query parameters with the object inside the opening parenthesis. The second chunk of the query seemed to denote the shape of the data returned, probably allowing for some stuff to be left out of an otherwise common shape of returned goods. The return properties do not seem to denote if a property is just a property or an array of many things which would then have their slated subproperties on each item in their collections.

Use the delete keyword in JavaScript to remove a property from an object.

Beyond this goofy example here, you can actually do something with the delete keyword! At the TypeScript Playground I wrote this TypeScript:

var foo = {
   bar: 13,
   baz: "lucky",
   qux: true
}
console.log({ ...foo });
delete foo.baz;
console.log(foo);

 
 

...which got turned into this JavaScript...

"use strict";
var foo = {
   bar: 13,
   baz: "lucky",
   qux: true
};
console.log(Object.assign({}, foo));
delete foo.baz;
console.log(foo);

 
 

When you run this stuff two objects get logged to the console and you can clearly see the baz on the first object and not the second object. Yay!

I am plumbing in a very complicated Angular 5 application.

There are no "controllers" beyond Angular 1, but this app has "controllers" in that it has classes that intertalk (making my own word) with services. The controllers are sometimes handing into the constructors of components and sometimes wrap a component. They are the top of a Russian doll hierarchy of components in a smart components/dumb components pattern, talking to services while the nested items just talk up and talk down the Russian doll nestings with inputs and outputs. Something I have learned the hard way when I cannot seem to find the right service they might speak to is that a controller might speak to a controller to speak to a service. Some other advice for myself:

  1. When you drill into the base class that something has and you still cannot find what you are looking for there, check to see if there is a grandparent.
  2. If you cannot find a dance partner for a method call nonetheless, search the whole of the codebase for the name.
  3. If you want to know what is using a method and it seems to be many things, put console.log with some variation in each place and run the app to see what is making the call.

Wednesday, November 27, 2019

ERROR TypeError: Converting circular structure to JSON

Well, if you just want to barf a snapshot of the latest thing up to the console it may be best to use the spread operator to get rid of a reference that could change instead of JSON.stringify inside JSON.parse which can lead to this error.

At the Network tab in Google Chrome Developer Tools at the app I am working on it is easy to see what calls are GraphQL calls as they are labeled as much.

Under the Headers subtab I can scroll down to Request Payload to see the actual graph being handed in!

Tuesday, November 26, 2019

finalize in a pipe off of an Observable

The finalize will run whenever data is done loading.

this.mySubscription = foo.pipe(finalize(() => {
      console.log('done loading');
   })).subscribe(data => {
      this.data = data;
   });

 
 

In Angular 5 you import this stuff the same way you would tap and catchError like so:

import { catchError, finalize, tap } from "rxjs/operators";

react to an error and then turn around and return a placebo Observable with of

This has this example of using catchError in a pipe to react to the error and then turn around and return a placebo, emptyish Observable with of so that there is not literally an error thrown.

catchError(() => { console.error('Error emitted'); return of([]); })

 
 

I cannot get this to work in the Angular 5 application I am working on. The version of RXJS is probably a bit too early for this.

Paymetric Tell-All

I suppose I can reveal some dirt on Vantiv's (now Worldpay's) acquisition Paymetric now that it's been so long that I'll never need a review from there, and there is more to tell than just Keith Deklerk getting in a fist fight in the Houston office (so said Angela Garza and Lisa Gschwind didn't contradict when I repeated it back to her). My immediate superior Michael Dozier had an adult son in the Autism/Asperger's spectrum and he literally believed in the Jenny McCarthy theories about how a shot at the doctor's office can inflict this condition on your child. He and his stay-at-home wife Lisa attempted to adopt a boy and a girl even though they already had three sons and the stress from the adoption process tested the wife so much that they had to back out of it. Michael told us all something along the lines of "she has been stable for years" but now she was "having thoughts" and that of course led me to certain conclusions. If this just seems like off limits and that I shouldn't go there, I have to say that I always thought Michael was a coward for getting Dip Manandhar to serve for a reference for me in the absence of doing so himself. I worked for him for two and a half years. Dip for his part wasn't so great at coughing up references for me. He seemed to help me on my first voyage because he had to and then he seemed to make up some story about being away in Nepal when I reached out six months later. Maybe he really was in Nepal. He's not my friend either way. Michael's superior at the time, James Osborn, had been Michael's underling once and was eventually promoted to be his boss and got out of writing code and into hiding in management. I recall a few times when Dip joked of how James' code had a code comment just for the starting of an array in some old dabbling that Dip had to unearth and deal with. I have a hunch that James wasn't much of a developer. James told me that his father was an alcoholic and I suspect the son took after the dad too. James would crawl in late a lot. When Mike Rivers was James' superior before Bill Wied and when he would visit from Atlanta there was often a happy hour after work in coordination and another coworker I had would joke of James being "sick" the day after these. There was a time when he and I and two others all had a training together and he showed up late for the training. I twice watched Bill Wied stand really close to Bridget Richards and ask her if she needed more time off when he learned of an issue with her as if he was really concerned about her. Bridget would smile at him with a shit-eating grin as if thinking "What is this bullshit?" and I suspect Bill's wife would have thought that too had she been a fly on the wall. Early on at my time at Paymetric, Asif Ramji reversed a previous policy of allowing employees to work from home on Fridays. Also there would be no flexibility as to when you had to be at work. Everyone had to be there until five, so no getting in early to cut out early to beat traffic home. Of course this angered a lot of the staff. James pulled all of us into his office, a few at a time, and then told us the news. After everyone was on board, James and Michael told David Streeter last and David Streeter threw a little fit in the middle of the office and was threatening to quit over having to be at work until five. Apparently he and his wife had some small dogs together, Schnauzers I think, and the new timetable wouldn't jive with some logistics challenges to do with the dogs. In short, David was too spoiled to be at work until five. I watched James suggest aloud in the middle of the office that perhaps he and Mike Rivers would just hide from Asif the fact that they would let employees leave before five. (I wonder what Lauren Allen and Rie Irish in the Atlanta office would have thought if they knew everyone in the Austin office didn't have to stay to five when the Atlanta office did.) Often when something went wrong middle management would introduce a new layer of micromanagement to give reassurances up because what else could they do as middle managers? Partway into my time at Paymetric the company started doing exhaustive code reviews because of this with a tool (SmartBear Collaborator) that could not aggregate commits and, as I like to check in early and often, this was ultimately the death sentence for me. It was the same story for me at @hand one job prior. I should have taken the "make one big commit" thing more seriously in retrospective, but I would also point out that almost everyone in the office would pick and choose what they took seriously. Michael asked everyone under his command to read the "Who moved my cheese?" book as an exercise and Dip just refused to do so and he got away with it. Posters were hung in the Austin office advertising our nine core values and when Asif, the CEO, visited from Atlanta, on a few occasions, he would preach to us about them while everyone (well, at least Dip) rolled their eyes. (I guess he didn't literally roll his eyes. He'd stand there looking grumpy, disgusted. You know what I mean, right?) They were all too vague to be actionable. Another example of cherry-picking what to care about would have been that business about not keeping the Austin employees in the office until five o'clock. At Paymetric I seemed to be the budgetary replacement for an Atlanta-based contractor with the idea being that it was best to have all of the developers in Austin. However, I'm not sure the Austin office was too in love with my addition to the team. I showed up wanting to work hard and that was quickly shot down and then I began to just coast. Two years later when management tried to shake me out of my slumber to get me to actually work hard again I didn't have the mindset for it and a voice inside was telling me that I could probably just get away with coasting yet as I had coasted for so long. Then things ended. It is tough that David could get away with leaving before five and that Dip could get away with not reading "Who moved my cheese?" but that I couldn't get away with checking in early and often but then I am also a tough person. I cannot say that I'll move on, but I will grow from this. The famous Nietzsche quote applies here. You know when Jeff Burkett was cut from Paymetric he told me that he was given three months severance in exchange for signing a piece of paper in which he would not badmouth the company on social media. In my case however, I don't think Bill, James, and Michael wanted Parisse Spelios in charge of human resources to even know about the decision making happing at least two states away (if you drive from Atlanta to Austin through Tennessee and Arkansas) and they just told me that I could stay until the end of the year while I looked for something else. It would to all appear as if I just quit. How convenient! I left work early that Friday, rattled, and then returned on Monday and resigned outright. I had a new job in less than a month. (I have some game.) Anyhow, the secrets were not contained in my case like they were with Jeff. Here they are for all to see! I may have more embarrassing stories under my own belt than anyone else I know, but if you stack a few others atop one another they can stand just as tall as me in that regard. Michael once suggested that he heard that the reason Jessica Wine's father Larry Wine was pushed out as CEO was because he was embezzling.

Monday, November 25, 2019

Sunday, November 24, 2019

My asynchronous ReST calls from my vanilla JavaScript are getting cached in IE11!

Try shoving something like this onto the end of the URL to fix this:

var url = '/api/play?hand=' + hand + "&nocache=" + new Date();

 
 

Do you see how the timestamp will randomize the URL and make each call unique?

the proper way to set the background image of an element in JavaScript which Edge and Chrome will respect

document.getElementById('x').setAttribute("style", "background-image: url('/" + y + "')");

Saturday, November 23, 2019

.getValue and .next in RxJS Observables

.getValue will synchronously get the immediate value out of the Observable while .next seems to set the next in the sequence value that you will hear while you are listening at length. Something already listening and not having had an update for a while should just get that update.

let cat = this.kittyObservable.getValue();
cat.lives--;
this.kittyObservable.next(cat);

 
 

This offers this on .next:

import { Observable } from 'rxjs';
 
const observable = new Observable(subscriber => {
   subscriber.next(1);
   subscriber.next(2);
   subscriber.next(3);
   setTimeout(() => {
      subscriber.next(4);
      subscriber.complete();
   }, 1000);
});
 
console.log('just before subscribe');
observable.subscribe({
   next(x) { console.log('got value ' + x); },
   error(err) { console.error('something wrong occurred: ' + err); },
   complete() { console.log('done'); }
});
console.log('just after subscribe');

 
 

It suggests that it spits back out:

  • just before subscribe
  • got value 1
  • got value 2
  • got value 3
  • just after subscribe
  • got value 4
  • done

Charity Miles

This ties into Pokémon GO and gives money to charity for miles you run in chasing Pokémon or something like that.

cancel culture

This is the manner in which angry idealists boycott something that is not politically correct enough. If Chick-fil-A isn't open on Sunday then no one should ever eat there.

Friday, November 22, 2019

RavenDB apparently has a way to do batch processing to rename misnamed properties in their NoSQL craftings.

This came up in a conversation with coworkers today wherein I vocalized my inclination to stay away from NoSQL stuff. I thought of how painful it is to deal with a property you realize you've misnamed after you've jammed thousands of documents into a database with that convention. It was suggested to me that it might be easier to just map to a better name at the client side than to start inserting new documents with a better name while you also either live with the misnaming or try to get rid of the misnaming. A coworker saw a split wherein it might be wise to go with NoSQL when the database is tightly coupled to the UI and would never be used outside of that UI. He saw this as the divide wherein one decides for or against relational data. I kind of heard him say that anything that isn't Mickey Mouse should get relational data.

Map a GraphQL query to a specific type in an Angular application.

Instead of just a semicolon here we could have something like so:

.map(response => response.data.AnalyticsFacet as FacetsModel)

 
 

A example of what is handed in for a query might be:

let query = `{
      AnalyticsFacet(analyticsRequest:
      {
         domain: "${domain}",
         analysisType: "${analysisType}",
         filterList: ${filter},
         countStrategy: "documents"
      })
      {
         label
         facets {
            label
            count
            id
         }
      }
   }`;

 
 

So you may see how this stuff maps back here is our FacetsModel:

export interface FacetsModel {
   maxError?: number;
   label: string;
   rank?: number;
   facets: BaseFacetModel[];
}

 
 

BaseFacetModel is this this:

export interface BaseFacetModel {
   count: number;
   label:string;
   id: any;
   maxError?: number;
   facets?: BaseFacetModel[];
}

Thursday, November 21, 2019

use SimpleChanges with the OnPush ChangeDetectionStrategy in Angular 5 to further minimize expensive operations in listening

Doing some filtering as seen in the third blob of code here before calling out to a method that transforms data handed in via an Input should be a performance improvement beyond wrapping the inbound value with the method call at the Input at the template itself. In the later scenario the filtering is going to happen whenever any one Input updates (even with the OnPush ChangeDetectionStrategy) and in the earlier scenario we can only react when our Input in particular is changing up.

The indeterminate state at checkbox type input controls is a thing in HTML and by HTML I mean JavaScript.

I found this example here of setting the setting and what the setting does is make the checkbox appear visually to be in some wishy-washy in-between state between checked and unchecked although this is all really just a visual cue as the checkbox is either checked or unchecked in the end in spite of appearances.

var checkbox = document.getElementById("some-checkbox");
checkbox.indeterminate = true;

 
 

In an Angular 5 template you could have something like this. Perhaps a good use case is for when a checkbox "governs" or "oversees" a bunch of other checkboxes and should only appear checked or unchecked if all of the children are checked or unchecked and should otherwise appear indeterminate if there is a splotchy what's what.

<input #foo type="checkbox" [indeterminate]="isSomethingErOther" />

Private variables and methods in an Angular 5 AOT component are NOT accessible at the template...

This is a big change between 4 and 5. (I think.) No. That is wrong. The distinction is whether or not you are using AOT. If you are using AOT you cannot access the private stuff.

looks like the parenthesis syntax of/for events up at templates in Angular 5 demands that the variable handed in be called $event

If you make up your own name the variable you are trying to pass ends up undefined.

When you add a new file and it doesn't seem to be a pending change in TFS at Visual Studio 2017...

Go to "Pending Changes" under the "Team Explorer" and then into the Detected items under Excluded Changes where you may loop the item in.

You may Associate or Resolve a related work item in TFS.

When you check in at "Pending Changes" you may be required to find a story at "Related Work Items" and next to anything you find (and there may be more than one) at the right there will be the word Associate in blue with a little dropdown arrow by it. It is possible that this arrow may be changed to Resolve to close out the story (or bug) upon check in and reassign it to whomever logged it so that they may test it. If that option is not there, double-click on the black copy at the left side of the pipe symbol before (i.e. to the left of) the blue copy to open a pane of options for the story or bug. Set the "State" to Active and the "Assigned To" to yourself. Save the story/bug and you should have the Resolve option once more.

Wednesday, November 20, 2019

Db is pronounced D-flat

https://www.codeproject.com/Articles/13639/Db-The-Future-Is-Coming and https://forums.autodesk.com/t5/net/db-d-flat-the-next-generation-programming-language/td-p/1599337 have some notes on whatever this was once supposed to be, the next thing after C# or whatever. I don't think this is the same thing as D or Dlang which was supposed to be the next thing after C++ (as was C#).

Tuesday, November 19, 2019

What is the difference between SimpleChanges and SimpleChange in Angular 5?

Well, they both import from the same place...

import { Component, Input, OnChanges, SimpleChanges, SimpleChange }
      from "@angular/core";

 
 

...but it is not fair to think of SimpleChanges as a collection of SimpleChange as it is not that, forgive me, simple. There will be a few SimpleChange types inside of a SimpleChanges type, but SimpleChanges is not an array of SimpleChange. Let me explain by telling you about a problem I was trying to solve today. In a Russian doll orchestration of Angular components in which a left nav and a graph with some breadcrumbs on it were nested inside an overarching manager, when the left nav's checkboxes where emptied out, the left nav needed to communicate up to the middleman via an EventEmitter and then down into the chart via an Input in order to smack the chart into reacting.

 
 

Specifically, I needed to just drop all of the chart breadcrumbs so in many ways I didn't need to send any complicated information up and then down again, I could just make SimpleChanges at the chart catch the right thing, perhaps a Date type. If the date was set to the immediate time in the left nav and was different when checked in the chart, that should do right?

public filtersModified(filters:any) {
   let isToClearFilter:boolean = false;
   if (Array.isArray(filters)) {
      isToClearFilter = true;
      filters.forEach((filter) => {
         if (filter.value && Array.isArray(filter.value)) {
            if (filter.value.length > 0) {
               isToClearFilter = false;
            }
         } else {
            isToClearFilter = false;
         }
      });
   }
   if (isToClearFilter) {
      this.clearAllFlag = new Date();
   }
}

 
 

This code would go in our middleman and react to an existing event bubbling up from the left nav. This approach is just as ghetto as can be. It makes for some really unintuitive code. The better thing to do is to hand over a complicated object and then let the component that needs it make sense of it. We will try this instead:

public filtersModified(event:any) {
      let isToChangeFilter:boolean = false;
      let filters:Array<SelectedFilterModel> = [];
      if (Array.isArray(event)) {
         isToChangeFilter = true;
         event.forEach((filter) => {
            if (filter.value && Array.isArray(filter.value)) {
               filters.push(<SelectedFilterModel>filter);
            } else {
               isToChangeFilter = false;
            }
         });
      }
      if (isToChangeFilter) {
         this.leftNavigationFilters = filters;
      }
}

 
 

We may use SimpleChanges and SimpleChange to make sense of things in the chart.

ngOnChanges(changes:SimpleChanges) {
   let leftNavigationFilters:string = 'leftNavigationFilters';
   if (changes[leftNavigationFilters]) {
      let change:SimpleChange = <SimpleChange>changes[leftNavigationFilters];
      let isToClearFilter:boolean = false;
      if (Array.isArray(change.currentValue)) {
         isToClearFilter = true;
         change.currentValue.forEach((filter) => {
            if (filter.value && Array.isArray(filter.value)) {
               if (filter.value.length > 0) {
                  isToClearFilter = false;
               }
            } else {
               isToClearFilter = false;
            }
         });
      }
      if (isToClearFilter) {
         this.resetSubTab();
      }
   }
}

Monday, November 18, 2019

Adobe Experience Manager allows you to build Adobe Forms.

Adobe Forms in turn allow for forms in PDFs. I guess you can submit stuff to web services via a PDF and also maybe hydrate a dropdown list's contents and the like off of a web service in a PDF. Great.

Skopos

These guys provide B2B services which provide data for machine learning consumption. A lot of it has legal themes such as proposed bills in Congress and the likelihood of their passage into law.

Sunday, November 17, 2019

There are two cameras side by side on the iPhone 11.

This came up while watching a football game today with coworkers (wherein the Minnesota Vikings beat the Denver Broncos after coming from behind from twenty to nothing). A coworker theorized that this will allow for algorithms to average the two photos taken together to make better pictures and make other magic happen. The plugin called Ad-Blocker for Google Chrome came up today. It theoretically allows you to watch YouTube videos while skipping the ads. The rest of the techworthy discussion at this football thing had to do with games. Sekiro is a samurai game. Return of the Obra Dinn is a mystery game. Zero Punctuation offers video game reviews.

Friday, November 15, 2019

subsort by a second thing in TypeScript

Just chase the first pair of return conditions with a second pair of return conditions.

public sortByRowDataLength(data): CircleTimelineDataModel {
   return data.headers.sort((yin, yang) => {
      if (yin.rowData.length < yang.rowData.length) {
         return 1;
      }
      if (yin.rowData.length > yang.rowData.length) {
         return -1;
      }
      if (yin.label > yang.label) {
         return 1;
      }
      if (yin.label < yang.label) {
         return -1;
      }
      return 0;
   });
}

I learned today about handing in negative numbers to .splice to get stuff off of the end of an array in JavaScript.

var prettyGirl = ['I', 'can', 'swear'];
prettyGirl.push('I', 'can', 'joke');
prettyGirl.push.apply(prettyGirl, ['I', 'say', 'whats', 'on', 'my', 'mind']);
prettyGirl.splice(-3).forEach((word) => {
   alert(word);
});

 
 

Above the -3 behaves like a 9 and we get three alerts containing:

  1. on
  2. my
  3. mind

 
 

Here the -7 acts like a 5.

var prettyGirl = ['I', 'can', 'swear'];
prettyGirl.push('I', 'can', 'joke');
prettyGirl.push.apply(prettyGirl, ['I', 'say', 'whats', 'on', 'my', 'mind']);
prettyGirl.splice(-7, 3).forEach((word) => {
   alert(word);
});

 
 

Giving...

  1. joke
  2. I
  3. say

the spread operator really is a better way to give something a new pointer in JavaScript in lieu of wrapping something with JSON.stringify and then wrapping that with JSON.parse

In this light JavaScript seems more sophisticated than C#.

Thursday, November 14, 2019

It's possible in JavaScript to make .reduce return an array if you pass in an empty array as a second parameter to .reduce after your function for magic contortions.

The first actor in the a/b logic is something you may set outside of the first item in your collection it would seem. You do so with a second parameter at the .reduce. All of a sudden .reduce seems less esoteric and something I might actually use in my day to day. This...

cleanFilter(oldArray:Array<FilterConfigurationModel>):Array<FilterConfigurationModel> {
   let newArray:Array<FilterConfigurationModel> = [];
   let counter:number = -1;
   oldArray.forEach((item)=>{
      let divide:string = " |>| ";
      if (item.displayName.indexOf(divide) >= 0) {
         let nameParts:Array<string> = item.displayName.split(divide);
         let copy = <FilterConfigurationModel>{
            ...item,
            displayName: nameParts[1]
         };
         if (!newArray[counter].filters) {
            newArray[counter].filters = new Array<FilterConfigurationModel>();
         }
         newArray[counter].filters.push(copy);
      } else {
         let copy = <FilterConfigurationModel>{
            ...item
         };
         newArray.push(copy);
         counter++;
      }
   });
   return newArray;
}

 
 

...may become:

cleanFilter(oldArray:Array<FilterConfigurationModel>):Array<FilterConfigurationModel> {
   let counter:number = -1;
   return oldArray.reduce((newArray, item) => {
      let divide:string = " |>| ";
      if (item.displayName.indexOf(divide) >= 0) {
         let nameParts:Array<string> = item.displayName.split(divide);
         let copy = <FilterConfigurationModel>{
            ...item,
            displayName: nameParts[1]
         };
         if (!newArray[counter].filters) {
            newArray[counter].filters = new Array<FilterConfigurationModel>();
         }
         newArray[counter].filters.push(copy);
      } else {
         let copy = <FilterConfigurationModel>{
            ...item
         };
         newArray.push(copy);
         counter++;
      }
      return newArray;
   }, new Array<FilterConfigurationModel>());
}

 
 

I suppose the example here is a TypeScript example in lieu of JavaScript example.

.sortBy in lodash is a lot like .sortBy in underscore.js

Following up on this example, something like this in underscore.js...

items = _.sortBy(items, function(item){ return item.value });

 
 

...is more or less the same with the function getting wrapped in an array in lodash like this:

items = _.sortBy(items, [function(item){ return item.value }]);

 
 

Add .reverse() just before the semicolon to make the ordering go the other direction in either case.

LGTM stands for: looks good to me

legit 'em

Report Definition Language or RDL

It's the name of the SSRS markup with things like Tablix in it. It's XML.

a Tablix in markup for SSRS reports...

...is a tabular/tablesque region for filing with data

breadcrumbing

...might be better bad English than breadcrumming

components inheriting from components in Angular

I typically see a pattern in which a component just inherits from a base class that is either abstract or merely worthless as a component all by itself as it not a component itself. However, this sort of implies that you could just make a component inherit from a component I guess the metadata properties like selector and template at the parent just get stomped over by those of the child if there is a child at play.

Wednesday, November 13, 2019

.and.callThrough()

...allows a spied upon method to be called normally in Jasmine testing.

some NUnit notes from tonight

In an Assert.IsTrue with two inputs the first is the condition and the second an exception message. An IConstraint I think is something like Is.True as opposed to maybe a comparison for equality.

Pick/BASIC

Pick is some old operating system with a database built in and the BASIC language in the mix. I heard about it for the first time today.

Monday, November 11, 2019

When handing an everchanging array into an Angular component as an Input, it may be wise to serialize and deserialize the array with every alteration.

Do something like the following to make sure the array has a new pointer every time is changes. That will keep the reference changing with the contents and allow change detection to pick up the changes. Otherwise the pointer does not change and nothing will proactively notice the guts beyond the pointer have been altered.

this.arrayChangingLocally.push(someChange);
this.arrayToHandOnwards = JSON.parse(JSON.stringify(this.arrayChangingLocally));

Sunday, November 10, 2019

what an analyst considers a data dictionary

This is some sort of a dump to a human readable format of what the columns in database tables are to Excel or some other format, maybe HTML in a wiki somewhere. If not a spit out from SQL, it could be some hand crafted representation too. In the PL/SQL space DESCRIBE or DESC is a keyword for digging this stuff up. Obviously in the T-SQL space DESC has a different meaning, descending. Instead, in the T-SQL space, try using EXEC sp_columns YourTableNameHere to get this info. Carrying some extra information about the table EXEC sp_help YourTableNameHere is, it would seem to me, a little better honestly. It doesn't have a few esoteric notes on columns its sister has like radix but you won't need to know about those truth be told. (Supposedly the radix is a length of an array, I don't even know what the context is within column typing.)

Saturday, November 9, 2019

LibreOffice

It is a freebie rival to Microsoft Office. With its suite of tools you may open and edit Microsoft Word files and PowerPoint files and so on.

If you write your own polling in vanilla JavaScript you may want a delay between trips to the server as constant bombardment offers potential fatigue with little payoff.

var date = new Date();
date.setSeconds(date.getSeconds() + 1);
while (new Date() > date) {

 
 

You may find a full second to be a wait too long. If so, there is an alternative.

var date = new Date();
date.setMilliseconds(date.getMilliseconds() + 100);
while (new Date() > date) {

Friday, November 8, 2019

'Foo' only refers to a type, but is being used as a value here.

This TypeScript error rears its head in Visual Studio Code when you are trying to new up an interface as if it were a class.

Thursday, November 7, 2019

I think I've talked myself out of a return trip to North Carolina.

The trip I took this year was kinda weak. Hurricane Dorian loomed and I ended up getting out of there early. The last night I was there I was in a Cary hotel room and there were several individuals fleeing the storm further inland from the coast. Also, I picked the week of Labor Day to go by accident and that meant fewer meetups with tech talks. Lame! Anyhow, I did get to see the Tech Triangle and while I have been telling myself I need to go back a second time, just today I have talked myself back out of that. A better visit does not have to be a bucket list to-do. Just so that everyone knows I have been to Charlotte once before. I was there on 8/28/2016 and I took this photo of a weird IHOP. The chicken sandwich or hamburger or what have you that I ordered had sour cream on it and it was inedible. I dug up the photo from Facebook just now.

 
 

Addendum 11/8/2019: Is that a tumor on the side of the head of the guy in the black shirt by the ear? Is that what the girl in the red shirt is gawking at?

How do I copy and paste some complicated JSON object logged to the console in Google Chrome Developer Tools to Notepad?

  • Right-click on the object and pick "Store as global variable"
  • The console will give you a name for the global variable you just made. It will be something like: temp1
  • Punch in copy(JSON.stringify(temp1)); at the console.
  • If you paste into Notepad everything will be jammed into one line, so paste into the left side of https://jsonformatter.org/json-pretty-print instead.
  • Copy everything from the right side to Notepad to have good JSON formatting.
  • Gson

    It is an open source library for serializing and deserializing JSON objects. It has prettier capabilities baked into it. The G is for Google. It was spun up at Google, get it?

    Filter out all of the matches on a single property within the objects in an object array based upon a second comparable array of blacklisted items in JavaScript.

    var good = [];
    var bad = [{id:27,alt:'h'},{id:69,alt:'i'},{id:42,alt:'j'},{id:23,alt:'k'}];
    var ugly = [{id:69,alt:'l'},{id:13,alt:'m'},{id:86,alt:'n'},{id:42,alt:'o'},{id:23,alt:'p'}];
    bad = bad.sort((yin, yang) => {
       if (yin.id > yang.id) {
          return 1;
       }
       if (yin.id < yang.id) {
          return -1;
       }
       return 0;
    });
    ugly = ugly.sort((yin, yang) => {
       if (yin.id > yang.id) {
          return 1;
       }
       if (yin.id < yang.id) {
          return -1;
       }
       return 0;
    });
    var spot = 0;
    ugly.forEach(function(value) {
       if(value.id != bad[spot].id) {
          if (value.id > bad[spot].id) {
             while (value.id > bad[spot].id && spot < bad.length-1) {
                spot++;
             }
          }
          if (value.id != bad[spot].id) {
             good.push(value);
          }
       }
    });
    console.log(good);

     
     

    Supposedly _.merge is the way to do this stuff with Lodash.

    Wednesday, November 6, 2019

    _.differenceWith in lodash

    This has a little cheatsheet on lodash and this might honestly be a play place with lodash and TypeScript. _.differenceWith will take three properties, first the array to keep stuff from, second the array to match against for throw aways, and third _.isEqual as a comparer to deep compare.

    PoE stands for Power over Ethernet

    This is a cable that passes power with data in one cable, or more specifically the system around as much.

    Tuesday, November 5, 2019

    How to do a merge for a hotfix in TFS within Visual Studio 2017.

    1. Pull down to a different folder the folder to merge to from the SAME workspace. Do not change workspaces.
    2. In the "Source Code Explorer" right-click on the folder containing the stuff you want to merge in and pick "Branching and Merging" and then "Merge..."
    3. Walk through the little wizard. Click the "Selected changesets" radio button. The "Source branch:" setting should be mapped to the stuff you want to merge in and the "Target branch:" should be mapped to where you want to merge to.
    4. The next page of the wizard will let you cherry pick what you want to merge.

    Make changes you've made in Visual Studio Code automatically show up as Pending Changes in TFS at Visual Studio without manually including the changes.

    The trick will come if you are using the Local Location.

    A simpler, maybe too simple, alternative to using a module as a static service in Angular.

    As opposed to this, something like this could live in a file by itself somewhere.

    export class Redundant {
       public doubleUp(key: string):string {
          return key + key;
       }
    }

     
     

    You could import it where you need it as you would normally and then turn around and use it like this:

    let song:string = "Daddy's little baby loves" + Redundant.doubleUp(" shortnin");

    Monday, November 4, 2019

    Make the same method conditionally return different stuff with MOQ.

    playerRepository.Setup(p => p.FindPlayer(It.IsAny<long>())).Returns((long id) => id==1
          ? new Player() { PlayerId = 1, PlayerIp = "127.0.0.1" }
          : new Player() { PlayerId = 2, PlayerIp = "128.0.0.1" }
       );

    custom application development

    No! Here is a less glamour note. If I just want to start a new message in Microsoft Teams, how do I do that? There is an icon at the upper left inside the blue top bar that looks like a pencil scribbling on a piece of paper. You can start a thread there and find someone you've not found before to correspond with as well. I guess this merits a blog posting as I couldn't find this today, well, not easily anyways. Dear reader, I know you are hoping for something more exciting than this. I guess I have failed in that regard.

    Saturday, November 2, 2019

    I saw Jason Webb speak on accessibility Wednesday night at JavaScript MN.

    There was some emphasis on American law. The Rehabilitation Act of 1973 was mentioned and it addresses the idea of discrimination based on disability but is really only applied to federal government work life. Of course Section 508 is an amendment to this, but a 504 amendment was also mentioned as well. It prohibits discrimination in programs that benefit from federal assistance. Opening the umbrella up farther yet is the Americans with Disabilities Act (ADA) which spills beyond any federal boundaries. This came to be in 1990. Domino's Pizza got in trouble, per the ADA, for having a web presence that was not accessible to the handicapped. This turned into a lawsuit and I guess they didn't avoid the Noid in that regard. Honestly, what could be worse than the "thirty minutes or it's free" campaign that actually killed some people? The lawsuit was likely comparatively easier. I digress. Anyhow, normally things don't escalate to the point of a lawsuit. Instead a "demand letter" will likely be submitted to an offending company and the offending company will shape up. At the web semantic tags in HTML get you 90% of the way to accessibility, things like header, footer, and main in-between, and, yes, there is a main tag. The 10% gap is closed by ARIA. WAI-ARIA is the Web Accessibility Initiative for ARIA of the World Wide Web Consortium, its spec for doing ARIA. CodePen is a coding playground where you may test this stuff and see other people's snippets for solutions. Because there is not an HTML tag for an autocomplete or a carousel, you have to delve into the ARIA stuff herein, as things gets trickier, beyond what sematic tags can express to a screen reader like JAWS. The header, footer, and main tags are "landmark tags" for similar concerns. The use of mobile devices as "assistive devices" has become super popular though 80% of the market for accessibility concerns is still just Windows operating systems flavored computers and laptops. JAWS and NVDA are just for Windows and testing just on Windows with just them in the screen reader space is seen as enough. Touch sticks help individuals with limited mobility tap the screen on assistive devices. Create a checklist in testing and Vox Product Accessibility Guidelines are recommended for as much. In personas for requirements building, have a persona with accessibility needs. The WCAG has twelve guidelines for accessibility based on four principles. The four principles follow and for the third one text should be written at a particular grade level slated as a standard. In the fourth, AT stands for accessibility technology.

    1. Perceivable – everyone can access the content
    2. Operable – everyone can interact with it
    3. Understandable – UI and content is clear
    4. Robust – works with many user agents and AT

    Emotion and styled components were two libraries mentioned by a Ben Ragsdale in a lightning talk before the main presentation by Jason Webb. He offered that if you tie CSS directly to a component you can know that it is only used for that component. Often times, this sort of thing takes place in template literals. Frequently at JavaScript talks the mention of a component will carry the subtext of a React component and at JavaScript MN in particular there seems to be a bit of a React bias. I guess React does have the largest "market share" of use and adoption in the modern JS space. Before the Ben Ragsdale lightning talk there was another lightning talk titled "Using the intersection of observers and hooks for SVG animations" and, yes, herein hooks implies React hooks. usehooks.com was recommended for getting into using hooks. You will want to import useState, useEffect, and useRef from 'react' to get the SVG animations stuff afloat. The IntersectionObserver will fire a callback when there is an overlap with the viewport as it was explained to me. Some code around as much was:

    useEffect(() => {
       const observer = new
             IntersectionObserver(
          ([entry]) => {
             setIntersecting(entry.isIntersecting);
          },
          { threshold: 0 ]
       );
       if (ref.current) {
          observer.observe(ref.current);
       }
       return () => {
          observer.unobserve(ref.current);
       };
    ], []);

     
     

    As a term, viewport just refers to the visible area of a web site in a web browser. It is not React-specific but the Intersection Observer API is. It will react to elements that change position relative to that of the viewport as best as I can tell. FramerMotion is an animation library that may be used with web hooks to get all of this to work smoothly. The observers/hooks/SVG lightning talk was given by a Dakota Sexton who works at White House Custom Colour. github.com/tinykite has her code.

    Thursday, October 31, 2019

    "see inner exception" runaround when trying to set the location of a TFS workspace to local

    The suggestion I see at Stack Overflow is that if you see this error you are trying to pull down too much locally and you had better chunk it up some if you really need all of it.

    Delete Shelveset

    To destroy one of your shelvesets in TFS, "go a finding" for your own shelvesets like so and then right-click on a line item and pick: Delete Shelveset

    C# 8 is finally here as of .NET Core 3.0.0.

    Both were released timed with .NET Conf on September 23rd it would seem. I just heard about it last night myself.

    Get rid of server sync with TFS.

    In Visual Studio 2017 at the Team Explorer's main splash page, reachable by clicking on the "Home" icon at the top which looks like a house, expand "Solutions" (below the eight buttons for "Project") and at the Workspace setting click the downwards pointing blue arrow. Next click Manage Workspaces... Edit a workspace here. At the dialog box for editing a workspace click Advanced > > and then set "Location:" from "Server" to "Local" before pressing the OK button.

    The L.I.O.N. acronym that people put by their names on LinkedIn stands for LinkedIn Open Networker it would seem.

    You know people and you're going places, get it? This is some wacky pseudostreetcred. Fun, fun.

    Wednesday, October 30, 2019

    At the Pending Changes tab in the Team Explorer in Visual Studio 2107, click on Pending Changes to pick one of the other top tier menu items of the Team Explorer.

    You don't have to go back to the "Home" view for everything as it turns out. A little menu of items, such as "Builds" for example, will materialize when you take this step. At Builds you may click Builds to similarly go back to Pending Changes. (Builds shows you if the most recent build passed or failed.)

    Cannot insert explicit value for identity column in table 'Players' when IDENTITY_INSERT is set to OFF.

    What are we to do about this error in Entity Framework Core implementations? Well, this might be an actual opportunity for me to provide some value with my blog as all of the Stack Overflow stuff I see just suggests decorating the field which cannot be written to with...

    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

     
     

    ...but that does not get at what was going on for me. The problem lay in attempting to add children of a parent and the column in question was to hold the reference key to the parent. In my case the parent was a Player which looked like so:

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    namespace FluffyNothing.Core.Objects
    {
       public class Player
       {
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public long PlayerId { get; set; }
          [Required]
          [MaxLength(15)]
          public string PlayerIp { get; set; }
          public virtual ICollection<Message> Messages { get; set; }
       }
    }

     
     

    The players have messages and the Message object looks like this:

    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    namespace FluffyNothing.Core.Objects
    {
       public class Message
       {
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public long MessageId { get; set; }
          [Required]
          [ForeignKey("PlayerId")]
          public Player Player { get; set; }
          [Required]
          public string Copy { get; set; }
          public DateTime Time { get; set; }
       }
    }

     
     

    Alright, the thing that threw the error looked like so:

    public void WriteMessages(Message player1Message, Message player2Message)
    {
       var optionsBuilder = new DbContextOptionsBuilder<PlayerContext>();
       using (var context = new PlayerContext(optionsBuilder.Options))
       {
          using (var transaction = context.Database.BeginTransaction())
          {
             context.Messages.Add(player1Message);
             context.Messages.Add(player2Message);
             context.SaveChanges();
             transaction.Commit();
          }
       }
    }

     
     

    I'm just trying to jam the messages in the database. That won't work. Instead I needed to query the parents and make an association to the parents. I did that like this:

    public void WriteMessages(Message player1Message, Message player2Message)
    {
       var optionsBuilder = new DbContextOptionsBuilder<PlayerContext>();
       using (var context = new PlayerContext(optionsBuilder.Options))
       {
          using (var transaction = context.Database.BeginTransaction())
          {
             List<Player> twoPlayers = context.Players.Where(p => p.PlayerId ==
                   player1Message.Player.PlayerId || p.PlayerId ==
                   player2Message.Player.PlayerId).ToList();
             foreach (Player player in twoPlayers)
             {
                if (player.Messages == null) player.Messages = new List<Message>();
                if (player.PlayerId == player1Message.Player.PlayerId)
                {
                   player.Messages.Add(player1Message);
                }
                if (player.PlayerId == player2Message.Player.PlayerId)
                {
                   player.Messages.Add(player2Message);
                }
             }
             context.SaveChanges();
             transaction.Commit();
          }
       }
    }