Friday, November 30, 2018

struggling to understand Injectors for the CDK modals of Angular 6

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

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

 
 

My service is such:

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

 
 

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

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

 
 

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

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

 
 

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

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

 
 

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

 
 

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

Set the emoji by your name to show you are at work in Slack.

  1. Click on your name at the upper left.
  2. Pick "Edit status..." from the menu that appears.
  3. Set an emoji and the text for the status by clicking on the existing settings.

Cash App allows for money transfers from mobile phones.

This has some details.

Tango Card

If you buy enough gift cards from a vendor in bulk odds are you can eventually get a price below the face value of the card if you are just buying enough. Tango Card has an interesting API for buying digital cards and assigning them on to others. You pay them face value and they do enough business to get a discount and thus not all of the money you give them gets passed along to the parties issuing the cards. This is how they make money. For average Joe developer trying to work with an API this is a good way to go as most other forums insist upon only indulging those who would buy in bulk brushing aside the business from small fish.

Thursday, November 29, 2018

.toBeTruthy() and .toBeFalsy()

These are legit Jasmine matchers.

required, optional, and query parameters in Angular routing

  1. This kinda touches on the distinction between paramMap and params.
  2. http://www.example.com/somethingerother;foo=13;bar=42;baz=69;qux=86 is an example of a URL with optional parameters and you'll note it is kinda like the usual get variables with the question marks and ampersands replaces by semicolons. (Query parameters have the usual question marks and ampersands per bullet 4 here.) The routerLink example here shows off optional parameters inside of the curly braces. Required parameters in contrast are those which make up URL chunks separated by forward slashes.
  3. <a [routerLink]="['/meh']" [preserveQueryParams]="true">meh</a> gives an example of preserving the query parameters when the paths change. You need the preserveQueryParams for the trick to work. The queryParamsHandling setting at bullet 8 here may go inline at the a tag I have here as well.
  4. Read queryParams off of the activatedRoute instance or the snapshot off of the activatedRoute instance as you would just params.

data-bound properties

In Angular, these imply Inputs at a selector tag.

ActiveRecord.NET

This is something bad. It stores objects for immediate, temp memory in databases. It is something old not to think about. Demons be gone!

Wednesday, November 28, 2018

some Angular routing stuff from today

  • <a [routerLink]=['/widgets', widget.id]"> is a good example of passing an id as a second route chunk at a link.
  • .forRoot will only get set and used once while .forChild may be reset from feature module to feature module. Using .forChild will not "reregister the router service" which would be problematic. Routes that exist randomly in a .forChild that are not mentioned at the .forRoot are legit in the big picture assuming that the feature module with the .forChild is referenced by the outermost God module. Note that .forChild route paths take precedence/priority over the .forRoot route paths if the .forRoot paths are just jammed in the outmost God module and this is probably for the best. If you make a dedicated module for the routing, then this module should probably go last in the imports (at the outermost God module) to achieve the same effect. Failing to do so can allow a wildcard route in the .forRoot stuff to catch a legitimate route for a .forChild crafting.
  • I redirectTo in Angular's routes make for a good way to accommodate URLs for old links to changed routes. If a redirectTo redirects to a route with a second redirectTo the second hop does not get made unfortunately.
  • If a link parameters array at a routerLink attribute at a tag in a template contains one one element, the square brackets around both the "routerLink" attribute directive designation and the value may be removed. Also don't put single quotes inside of the double quotes at the assignment. This is the shortcut syntax for routerLink.
  • this.router.navigateByUrl('/foo'); varies from this.router.navigate('/foo'); as the former will drop any secondary routes. Herein router is the Router imported from '@angular/router' and note that the absence of square brackets wrapping the '/foo' paths is supposedly perfectly legit as a shortcut instead of an array of one item. Honestly, I could not get it to work today. It seems to work for .navigateByUrl but not .navigate alone.
  • At http://www.example.com/foo(bar:baz) the stuff in parenthesis is the secondary route.

Fake an API's interaction in an Angular app!

Use this:

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';

shell in Visual Studio Code

The "Terminal" or perhaps "Integrated Terminal" option under the "View" menu at VS Code/Visual Studio Code will allow you to run npm commands via PowerShell.

Angular base paths and the Angular CLI

In an Angular application, defining the base path such that it is a folder deeper than the root immediately below the domain name may be wise. Confidence that a production environment will not mandate that the application be tucked into a folder may be foolish.

 
 

ng build --base-href /YOURNAMEHERE/

...will modifiy the base path via the Angular CLI.

 
 

ng build --bh /YOURNAMEHERE/

...is also legit. A base HTML tag sets the base path ultimately beyond all of the contortions above. Strange errors which may appear at the console in Google Chrome Developer Tools due to a bad setting with this stuff include:

  • Refused to apply style from ' http://www.example.com/yin/yang.css ' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
  • Uncaught ReferenceError: System is not defined

Tuesday, November 27, 2018

some Spring API notes

  1. Annotations in Spring are the bits of markup with a leading at symbol, kinda like decorators in TypeScript.
  2. Spring started out as an IoC container.
  3. Enterprise JavaBeans in Java are not needed for Spring and typically one does Spring without them. The EJBs are heavier, clunkier, other architecture.
  4. POJO stands for Plain Old Java Object.
  5. A template method pattern is the basic theme of an architecture implementation, defining the basic behavior of an application at a high level.
  6. You have to use Maven or Gradle to download Spring stuff.
  7. Java Database Connectivity (JDBC) is an inferior approach to Spring.
  8. Spring MVC is a web framework and Spring Data is for access to the database.
  9. @ResponseBody is for converting a message into an HTML response. If a @Controller is changed into a @RestController you do not explicitly need the @ResponseBody syntax.
  10. We need a mapping inside of a controller to map a route to a URL. Mappings have a distinction between @GetMapping and @PostMapping for example.
  11. The pom.xml file (POM being Project Object Model) is the base configuration file in a Maven project.
  12. A @PathVariable extends a URL/mapping to allow for an id to be handed in for a Get or a Delete as the last bit of a route. If you need a more specific variable with a name in the stuff after the question mark in a URL you may use a @RequestParm for such.
  13. @ExceptionHandler can return an error message.
  14. JUnit is the defaut testing framework. Spring Boot, AssertJ, and Hamcrest (anagram of matchers) are rivals. JSONPath is for walking what is in a JSON object and Mockito is for mocking.
  15. HatEoAS uses JSON with URL links in it. The Richardson Maturity Model (named for a Leonard Richardson) has HatEoAS as the best way to go, better than just REST which is in turn better than just services, not-quite-REST without concern for the HTTP (hypertext transfer protocol) verbs, which is in turn yet better than the swamp of POX (Plain Old XML).

JIT is not AOT.

The compiler in Angular that is not the ahead-of-time compiler that is gonna slurp your component templates into what is compiled or squawked at if uncompilable is the just-in-time compiler. The just-in-time compiler is the default way to do things.

"Show tab previews" and "Hide tab previews" in Microsoft Edge.

This is a toggle that either looks like a chevron or an upside-down chevron in sort of a V shape for showing thumbnails for the various tabs open in Edge at Windows 10. Click the chevron to hide this stuff. (It will be at the very top to the right of the tabs.) It's awful. It takes up way too much real estate. Who actually asked for this?

There is a prefetch feature for Angular routing. You may use it to spin a spinner and not show the thing you are to load until it is prepped and ready.

This and this suggests that one may use the NavigationStart, NavigationEnd, and NavigationCancel events described here and here along with also an NavigationError event to display a spinner or hourglass or the like until the preprep at a destination is done and then drop the effect. It might be the ngAfterViewInit event firing at a component timed with the NavigationEnd event at the routing. I'm not certain yet. I also am unsure of how to delay this event while awaiting a promise that will bring back data from an API endpoint to hydrate the view with stuff.

Monday, November 26, 2018

Sunday, November 25, 2018

trying to get started with the modals in the Angular CDK

Alright, I have not yet been able to make a modal that sits just anywhere or that allows for data to be handed to it or that allows you to click an X to close the modal, but I will share with you what I have. First of all, I penned this blog posting which speaks to how to get rid of a flickering scrollbar that the CDK's paginated list of records can cause. I have had to alter the CSS which goes in styles.css like so:

.cdk-overlay-connected-position-bounding-box {
   display:none !important;
}
.cdk-overlay-container div[dir=ltr] {
   position: absolute;
   margin-top: -500px;
   margin-left: 20px;
   width: 200px;
   height: 200px;
   border: 1px solid #000000;
   background-color: white;
}

 
 

The second style here is the style for our modal and as you can see it is pretty ghetto right now. Hey, I'm just getting started. The dir inline attribute of an HTML tag attempts to define which way text should read and the CDK will make a div with this set to ltr for left-to-right (as opposed to perhaps rtl for right-to-left) and this div wraps the guts of our modal or, you could say, is our modal really. Alright, we are going to need a component for our modal like so:

import { Component} from '@angular/core';
import { President } from '../models/president.model';
@Component({
   selector: 'modal',
   templateUrl: './modal.component.html',
   styleUrls: ['./modal.component.css']
})
export class ModalComponent {
   constructor(){
   }
}

 
 

The CSS and the HTML can be whatever you want them to be for now. If you just want to say "Hello World" well that is about how far I can get right now too. We are going to need a service for our component like so:

import { Injectable } from '@angular/core';
import { ModalComponent } from '../layout/modal.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { Overlay } from '@angular/cdk/overlay';
import { President } from '../models/president.model';
@Injectable()
export class ModalService {
   constructor(private overlay: Overlay) { }
   public open(president:President) {
      const overlayInstance = this.overlay.create();
      const filePreviewPortal = new ComponentPortal(ModalComponent);
      overlayInstance.attach(filePreviewPortal);
   }
}

 
 

Make the modal open from another component with a method like this:

openModal(president:President): void {
   this.modalContract.open(president);
}

 
 

At your outermost God module you need to loop in the service at providers and the component at declarations. The component must also be listed at a new metadata property called entryComponents here which looks like so:

entryComponents: [
   ModalComponent
]

Friday, November 23, 2018

Tuesday, November 20, 2018

subtext

...is another old blog platform for .NET like dasBlog. This should take you back in time a decade.

.xlsm files versus .xlsx files

An .xlsm is like a .xlsx Excel sheet. It can be opened by Microsoft Excel 2007 and greater. The m stands for macro and the sheet is somehow friendly for macros too.

the "Macintosh" CSV in Microsoft Excel 2010

When you save an .xlsx as a .csv in Microsoft Excel 2010 at Windows 10 there will be three options:

  1. CSV (Comma delimited) (*.csv)
  2. CSV (Macintosh) (*.csv)
  3. CSV (MS-DOS) (*.csv)

The Macintosh option behaves goofy at Windows 10, not honoring carriage returns for new rows.

Monday, November 19, 2018

POP3 versus SMTP versus IMAP

Version 3 of Post Office Protocol allows you to receive emails. Internet Message Access Protocol allows you to read emails kept on a remote server which will NOT be popped off to your Outlook client. The POP3 approach destroys the records at the remote locale once you have them locally while the IMAP way just looks to the remote locale. Get it? Simple Mail Transfer Protocol is for sending NOT receiving.

Postfix

It's an open-source mail server. Send emails with this stuff from your FreeBSD machine.

Friday, November 16, 2018

SlideShare

This is a place on the web run by LinkedIn for tucking away your PowerPoint slides from your tech talks so that the public might have at them. You may search by topic for slide shows, etc.

Thursday, November 15, 2018

flickering scrollbar when using the pagination controls at an Angular Materials data table in an Angular 6 application?

This is a thing! Assuming you are doing something like this, you may see the scrollbar at the right of the browser spaz a bit when you mouse over the pagination controls. This comes from changes inside of a div that has the cdk-overlay-container class on it which is the last element inside of the body tag sitting just before the close body tag. If you don't remember putting that div there it is because you didn't. It is imposed by the CDK. Inside the div are two to four divs depending on if two to four pagination controls are active (you can't page back or go to the beginning of the list if you are on the first page after all, so sometimes two controls will be disabled) with a class of cdk-overlay-connected-position-bounding-box on them and inside of each of these is a div with both cdk-overlay-pane and mat-tooltip-panel at the class setting. These divs nested three tiers deep start out empty, but when you mouse over the pagination controls something gets put inside of them and that causes the page height to change. To fix this put something like this...

.cdk-overlay-container {
   display:none !important;
}

 
 

...inside of styles.css or whatever you have named your "outermost" God stylesheet which has styles that are imposed everywhere in the application as opposed to component-specific stylesheets. You don't want to use an ::ng-deep trick in any of the component stylesheets to try to get this fixed. Slay the serpent by just cutting its head off at the head itself. No subtle surgery! This hack will keep all of the divs I mentioned above from appearing and as best as I can tell this comes with no side effects.

 
 

Addendum 11/24/2018: Perhaps .cdk-overlay-connected-position-bounding-box would be better to use as the class as .cdk-overlay-container can also wrap the div that holds a modal.

Wednesday, November 14, 2018

Do stuff with the Venafi API!

You need to get a token for authentication before you may do much else.

string user = "God";
string pass = "letmein";
string apiUrl = "https://certificateservices.example.com/vedsdk/";
using (WebClient webClient = new WebClient())
{
   string credString = "{\"Username\": \"" + user + "\", \"Password\": \"" + pass + "\"}";
   byte[] credBytes = Encoding.Default.GetBytes(credentialsString);
   byte[] back = webClient.UploadData(apiUrl + "authorize", "POST", credBytes);
   JObject j = (JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(back));
   string
token = j["APIKey"].ToString();
   return
token;
}

 
 

The JSON object coming back has two properties on it, one advertised above (APIKey, a Guid) and ValidUntil which is a time to die. You may affirm a token, so to speak, like so:

string apiUrl = "https://certificateservices.example.com/vedsdk/";
using (WebClient webClient = new WebClient())
{
   webClient.Headers.Add("X-Venafi-Api-Key",
token);
   byte[] back = webClient.DownloadData(apiUrl + "authorize/checkvalid");
   JObject j = (JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(back));
   return j;
}

 
 

Download a certificate by its "distinguished name" like so.

string apiUrl = "https://certificateservices.example.com/vedsdk/";
string name = "\\\\VED\\\\Policy\\\\@MyPolicy\\\\Certificates\\\\MyFolder\\\\MyCert";
using (WebClient webClient = new WebClient())
{
   webClient.Headers.Add("X-Venafi-Api-Key",
token);
   string url = apiUrl + "certificates/Retrieve?CertificateDN=" + name;
   url = url + "&Format=Base64";
   byte[] response = webClient.DownloadData(url.Replace("\\\\","\\"));
   return response;
}

 
 

Try to renew a certificate returning true upon success and false upon failure.

string apiUrl = "https://certificateservices.example.com/vedsdk/";
string name = "\\\\VED\\\\Policy\\\\@MyPolicy\\\\Certificates\\\\MyFolder\\\\MyCert";
using (WebClient webClient = new WebClient())
{
   webClient.Headers.Add("Content-Type", "application/json");
   webClient.Headers.Add("X-Venafi-Api-Key",
token);
   byte[] go = Encoding.Default.GetBytes("{\"CertificateDN\": \"" + name + "\"}");
   byte[] back = webClient.UploadData(apiUrl + "certificates/renew", "POST", go);
   JObject j = (JObject) JsonConvert.DeserializeObject(Encoding.UTF8.GetString(back));
   bool isSuccess = Convert.ToBoolean(j["Success"].ToString());
   if (!isSuccess) return false;
}
while(true)
{
   JObject workToDoJson;
   JObject inErrorJson;
   JObject certificateVaultIdJson;
   using (WebClient webClient = new WebClient())
   {
      webClient.Headers.Add("Content-Type", "application/json");
      webClient.Headers.Add("X-Venafi-Api-Key",
token);
      string requestString = "{\"ObjectDN\": \"" + name + "\",";
      requestString = requestString + ""\"AttributeName\": \"Work To Do\"}";
      byte[] go = Encoding.Default.GetBytes(requestString);
      byte[] response = webClient.UploadData(apiUrl + "config/read", "POST", go);
      string workToDo = Encoding.UTF8.GetString(response);
      workToDoJson = (JObject)JsonConvert.DeserializeObject(workToDo);
   }
   using (WebClient webClient = new WebClient())
   {
      webClient.Headers.Add("Content-Type", "application/json");
      webClient.Headers.Add("X-Venafi-Api-Key",
token);
      string requestString = "{\"ObjectDN\": \"" + name + "\",";
      requestString = requestString + ""\"AttributeName\": \"In Error\"}";
      byte[] go = Encoding.Default.GetBytes(requestString);
      byte[] response = webClient.UploadData(apiUrl + "config/read", "POST", go);
      string inError = Encoding.UTF8.GetString(response);
      inErrorJson = (JObject)JsonConvert.DeserializeObject(inError);
   }
   using (WebClient webClient = new WebClient())
   {
      webClient.Headers.Add("Content-Type", "application/json");
      webClient.Headers.Add("X-Venafi-Api-Key",
token);
      string requestString = "{\"ObjectDN\": \"" + name + "\",";
      requestString = requestString + ""\"AttributeName\": \"Certificate Vault Id\"}";
      byte[] go = Encoding.Default.GetBytes(requestString);
      byte[] response = webClient.UploadData(apiUrl + "config/read", "POST", go);
      string certificateVaultId = Encoding.UTF8.GetString(response);
      certificateVaultIdJson = (JObject)JsonConvert.DeserializeObject(certificateVaultId);
   }
   if (inErrorJson != null)
   {
      string inErrorsResult = inErrorJson["Result"].ToString();
      string inErrorValues = inErrorJson["Values"].ToString();
      if (inErrorsResult != null && inErrorValues != null)
      {
         int inErrorResultValue = Convert.ToInt32(inErrorsResult);
         if (inErrorResultValue == 102 && inErrorValues == "[]")
         {
            string workToDoJsonResult = workToDoJson["Result"].ToString();
            string certificateVaultIdResult = certificateVaultIdJson["Result"].ToString();
            if (workToDoJsonResult != null && certificateVaultIdResult != null)
            {
               int workToDoJsonResultValue = Convert.ToInt32(workToDoJsonResult);
               int certificateVaultIdResultValue = Convert.ToInt32(certificateVaultIdResult);
               if (workToDoJsonResultValue == 1 && certificateVaultIdResultValue == 1)
               {
                  return true;
               }
               if (workToDoJsonResultValue == 0 || certificateVaultIdResultValue == 0)
               {
                  return false;
               }
            }
         }
         else
         {
            return false;
         }
      }
   }
}

 
 

Create a certificate.

string apiUrl = "https://certificateservices.example.com/vedsdk/";
string name = "\\\\VED\\\\Policy\\\\@MyPolicy\\\\Certificates\\\\MyFolder\\\\MyCert";
using (WebClient webClient = new WebClient())
{
   webClient.Headers.Add("Content-Type", "application/json");
   webClient.Headers.Add("X-Venafi-Api-Key",
token);
   string gunk = "{\"ObjectDN\": \"" + name + "\", \"Class\": \"X509 Certificate\",";
   gunk = gunk + ""\"NameAttributeList\": [";
   gunk = gunk + "{\"Value\": \"Yin\",\"Name\": \"Organizational Unit\"},";
   gunk = gunk + "{ \"Value\": \"Yang\", \"Name\": \"Description\"}";
   gunk = gunk + "]}";
   byte[] request = Encoding.Default.GetBytes(gunk);
   byte[] back = webClient.UploadData(apiUrl + "Config/Create", "POST", request);
   JObject j = (JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(back));
   return j;
}

 
 

Create a server specification at the VEDAdmin GUI. An IdentityType of 1 is for a user and an IdentityType of 2 is for a security group. 8 is for a distribution group for email updates I suppose and you may add these three numbers together in a Unix manner to search across more than one IdentityType. I add one contact to the server below, but you may add more. It is alright to have more than one "Value" of "Contact" to do so.

string contact = "";
string apiUrl = "https://certificateservices.example.com/vedsdk/";
string serverName = "\\\\VED\\\\Policy\\\\@MyPolicy\\\\Devices and Apps\\\\MyServer";
string creds = "\\\\VED\\\\Policy\\\\@MyPolicy\\\\Access Credentials\\\\MyCredential";
using (WebClient webClient = new WebClient())
{
   webClient.Headers.Add("Content-Type", "application/json");
   webClient.Headers.Add("X-Venafi-Api-Key",
token);
   string requestString = "{\"Filter\": \"MyGroup\", \"Limit\": \"1\", \"IdentityType\": \"2\"}";
   byte[] requestBytes = Encoding.Default.GetBytes(requestString);
   byte[] dirtyResponse = apiUrl + "Identity/Browse", "POST", requestBytes);
   string cleanResponse = Encoding.UTF8.GetString(dirtyResponse);
   JObject json = (JObject)JsonConvert.DeserializeObject(cleanResponse);
   contact = (string)json["Identities"][0]["Universal"];
}
using (WebClient webClient = new WebClient())
{
   webClient.Headers.Add("Content-Type", "application/json");
   webClient.Headers.Add("X-Venafi-Api-Key",
token);
   string gunk = "{\"ObjectDN\": \"" + serverName + "\", \"Class\": \"Device\",";
   gunk = gunk + ""\"NameAttributeList\": [";
   gunk = gunk + "{\"Value\": \"" + Guid.NewGuid() + "\", \"Name\": \"Client ID\"},";
   gunk = gunk + "{\"Value\": \"AD+MS:" + contact + "\",\"Name\": \"Contact\"},";
   gunk = gunk + "{\"Value\": \"my.server.example.com\",\"Name\": \"Host\"},";
   gunk = gunk + "{\"Value\": \"" + creds + "\",\"Name\": \"Credential\"}";
   gunk = gunk + "]}";
   byte[] go = Encoding.Default.GetBytes(gunk);
   byte[] dirtyResponse = webClient.UploadData(apiUrl + "Config/Create", "POST", go);
   string cleanResponse = Encoding.UTF8.GetString(dirtyResponse);
   JObject json = (JObject) JsonConvert.DeserializeObject(cleanResponse);
   return json;
}

Tuesday, November 13, 2018

It ain't Waco!

Well, for a while Seattle-based Amazon has been keeping us in suspense as to where their second facility, which will house yet more racks of servers I'm sure, will be located. Recently, expectations have been changed with an announcement that it would be split across two locales and as of today we know that the two locales will be New York and Arlington and by Arlington I mean the Arlington in Virginia not that border town in DFWland Texas. I remember seeing Waco, Texas on the short list of possibilities, but alas it is not to be. David Koresh's ghost deserves to be trapped someplace boring and that's not gonna change anytime soon.

WebGL

Short for "Web Graphics Library" this is a JavaScript API that allows one to make 3D graphics inside of a canvas tag in HTML. The spinning cube here would be an example. This offers that "applications that export to OBJ are 3ds Max, EIAS, Lightwave, Maya, Modo and Solidworks" wherein a Wavefront .obj (probably short for "object") is the format that you'll use for this stuff. Basically one would build in 3ds Max, EIAS, Lightwave, Maya, Modo or Solidworks and then export to the .obj format to get their stuff into WebGL. (3ds Max is a renaming of 3D Studio Max, a sequel of sorts to a DOS program that was just called 3D Studio, while EIAS stands for Electric Image Animation System and is pronounced alias.) Note: No mention of MetaCreations Bryce. LOL (acronym: laugh out loud)

two differences between Observables and Promises

With Observables you may hold an ear open as described here, and what is more with Observables you do not get anything back until you start a .subscribe or use the async pipe in the Angular markup. "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis clarifies this on page 214. This same page mentions .complete() to as if it were kinda like .done() but this is going to be yet another mistake in the book. The explicit need to start listening and the ongoing listening kind of explains why you can't really have an Observable that returns void, eh?

Monday, November 12, 2018

the Promise generic in TypeScript

Stack Overflow has this example of it:

function test(arg: string): Promise<number> {
   return new Promise<number>((resolve, reject) => {
      if (arg === "a") {
         resolve(1);
      } else {
         reject("1");
      }
   });
}

 
 

Here is an example of using their example:

let input = "a";
test(input).then(
   (yin:number) => { console.log(yin + yin) },
   (yang:string) => { console.log(yang) }
);

 
 

The "a" value above is going to trigger the first function in the .then implementation while changing "a" out for a "b" would trip the second function. This has some notes of what is new in TypeScript 3.1 and its first talking point is "Mapped types on tuples and arrays" for which it offers these three lines of code:

type MapToPromise<T> = { [K in keyof T]: Promise<T[K]> };
type Coordinate = [number, number]
type PromiseCoordinate = MapToPromise<Coordinate>;

 
 

The Promise generic appears again! How may we use the three lines of code immediately above? Well, we can have them chase the function from Stack Overflow at the top of this blog posting and then chase all that with this:

let myPromiseCoordinate: PromiseCoordinate = [test("a"), test("b")];
myPromiseCoordinate.forEach((myPromise: Promise<number>) => {
   myPromise.then(
      (yin:number) => { console.log(yin + yin) },
      (yang:string) => { console.log(yang) }
   );
});

Sunday, November 11, 2018

The past is the past.

I dabbled in what you see here this month. It didn't go so well. I guess I got a jewel case out of it.

 
 

Addendum 11/12/2018: Honestly, I threw the jewel case away.

contravariance galore in TypeScript!

In spite of what I heard in this talk about how it was getting taken away it still seems pretty rampant and hard to police. Look how easy it is to sidestep a constructor on a class.

class Person {
   public Age: number;
   public BirthDate: Date;
   public IsMale: boolean;
   public Name: string;
   
   constructor(birthDate: Date) {
      this.BirthDate = birthDate;
      this.Age = new Date().getFullYear() - birthDate.getFullYear();
   }
}
let Alice: Person = new Person(new Date(1969, 1, 1));
console.log(Alice.Age);
console.log(Alice.BirthDate);
let Bob: Person = <Person>{};
console.log(Bob.Age);
console.log(Bob.BirthDate);

 
 

This code puts the following to the console:

  • 49
  • Sat Feb 01 1969 00:00:00 GMT-0600 (Central Standard Time)
  • undefined
  • undefined

 
 

I noticed this trick on page 208 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis. I would consider {} kind of like object in C#. This really feels like casting a parent to a child.

Saturday, November 10, 2018

I saw Mark Dobossy speak on version 4 of Ionic at AngularMN on Wednesday night.

It's quite different! The first three versions of Ionic, a means to get Angular to be mobile-friendly with all of the swipe/touchability/etc. whistles and bells associated with hybrid apps, used Cordova to do what you would do with Cordova, access the camera, geolocation, and other similar goodies on a smartphone as if the app were a native application. As of version 4 Ionic uses Capacitor instead to do these things and it retreats in terms of architecture to really only be to do with the user interface and not something more sweeping. Mark showed off a helpful planner application that he made for a confused John Travolta to help him manage his affairs and in doing so went through some of the basic CLI command line commands to spin it up. The boilerplate code was an awful lot like that of an Angular application with a recognizable base module, base component, and default routing implementation. He also showed off a BLE-LED (BLE stands for Bluetooth Low Energy and thus a BLE-LED is an LED display you may talk to across Bluetooth) project he worked on with his son too and got an LED display to change from saying "Hello World" in red to saying "hello angular MN" in sort of a teal color at some fashion of Arduino implementation from the TypeScript code of an Angular (Ionic) app. There was talk of interacting with some other things too such as a QR code reader (QR codes being those square images filled with little black and white smaller squares that show up on packages that you may scan to get a URL) but I don't know that is wildly different than the camera standalone. So how does Capacitor do what it does and what makes it different than Cordova? Capacitor is a native (Objective-C/Swift/Java) application that will run at either an iPhone or an Android device which does nothing but display a browser. The browser itself doesn't look like a browser in that it has no navigation menu or anything like that and you may use this native app that has a browser in it as if the whole experience were a native experience and Average Joe on the outside looking in will never know there is even a browser involved as the hack is faked so well. Ionic 4 is sort of portrayed even as something that lets you write "native" apps in Angular, but, of course, this is a bit of stretch as the TypeScript compiling to JavaScript does not compile down again to Objective-C or Swift or Java but instead there is the before-mentioned trickery. You are writing Angular for just another browser in the end. Your Angular code surfaces inside of the browser inside of the native app. This is not Titanium. There is the concept of "code push" in Ionic 4 and once you get an application successfully listed in an app store on a particular platform you may push down to the devices code updates in lieu of having to try to fight to get each new version of your app through the app store again. Mark Dobossy was using the XCode IDE and he mentioned that Leaflet OpenStreetMap tends to get updates a little faster than Google Maps.

Friday, November 9, 2018

Uninstall something at Windows 10.

  1. From the start menu (click the clickable windows symbol at the far lower left of the screen) click on the gear for "Settings"
  2. Here there will be options for System, Devices, Phone, Network & Internet, Personalization, Apps, Accounts, Time & Language, Ease of Access, Privacy, Update & Security, and Search and you should click "Apps"
  3. Click "Apps & features" at the left.
  4. There will be a list of apps, click the one that needs to go away.
  5. An "Uninstall" button will appear and you should click it.

Thursday, November 8, 2018

Max

This is one of the aggregate functions, not unlike MIN, in T-SQL. Below, given all the Number values for a particular Name, this will place the highest in the second column.

SELECT Name, Max(Number) FROM Nonsense
GROUP BY Name

Tuesday, November 6, 2018

Structural, Behavioral, and Creational

These are the super categories of design patterns. Each of the design patterns you can think of fits into one of these three buckets though I cannot really tell you what goes where. I believe the facade pattern is a structural pattern for example.

Monday, November 5, 2018

Dojo methodology of Agile

Sprints are three days long... the end of the third day is the retrospective...

Azure Functions

These are like the cloud functions mentioned here only they are written in C# instead of JavaScript.

Catfishing

A catfish pretends to be someone they are not on social media.

Sunday, November 4, 2018

Capybara

It is a testing framework.

I saw four lightning talks at JavaScript MN on Halloween night and appropriately the first and best was on spooky JavaScript.

Jonathon Stierman, who actually works at space150 which now hosts JavaScript MN, gave a talk called Spooky Weird Fun JavaScript. He went into a lot of the type coercion wackiness. Anything may be coerced into Boolean form for a truthy or falsey check obviously. Some specific results are scary. This is true for example:

if ("" == 0) {

 
 

This should only scare you if you are a noob as herein we are comparing values and not types as we would if we were using the strictly equals operator with three equal signs in lieu of the equality operator with two equals signs. This however will be false which is rather terrifying:

if (new String('Hello')===new String('Hello')){

 
 

Boolean operations do not always return Booleans. For example our variable here will end up with 42 in it:

const notaBoolean = (true && 42);

 
 

There is a mystical (Jonathon's term) thing called the AIS which stands for automatic semicolon insertion. You cannot really break the return keyword and the value to be returned (followed by a semicolon) onto two separate lines of code in JavaScript and expect it to behave as just one line of code as though the semicolon you can see with your own eyes denotes the end of the one line. Instead an implicit semicolon will be placed after the return keyword in this circumstance sabotaging what you are attempting. The return keyword and the thing to be returned have to sit on the same line together in JavaScript. There is no way to turn the AIS off. This is also why an open curly brace must immediately follow an if statement on the same line instead of being the first character of a new line as is the preferred convention in C#. jjencode was suggested to be an interesting obfuscation tool for JavaScript though frontend obfuscation is kinda silly. Jonathon showed us some examples of it and pretty much all of the human readable characters came out. Names were just made up of dollar signs and plus symbols and underscores.

Ja'keh Clark is a recent graduate of Prime Digital Academy, a coding boot camp, with a heavy prior history as a graphic artist who created an app called "The Loop" for one of his Prime projects. He showed it off in his talk and it is basically a let's-give-each-other-professional-references application. Of course this is a subset of what one may do already on LinkedIn but an emphasis of this talk was on how LinkedIn ain't all that. Ja'keh found it sanitized in a dehumanizing way and not really a venue for people to distinguish themselves or be more than résumés.

Arthur Taylor gave a talk on parsing big data with JavaScript. His example had to with going through loan data from quarter one of this year and determining who was thus worthy for another loan, i.e. who was a smart bet and a good investment. The Python pandas library was used in his work. It is for data analysis.

Michael de vera has a history in working with React Native, which really is what is sounds like, i.e. building native (Objective-C/Java/Swift) code for mobile devices by compiling JavaScript to it not unlike the Titanium of yore. He has been experimenting with Redux Thunk Middleware and what a thunk does is it allows you to call off to a handful of API calls at once while, instead of waiting for them all to return so that you may do something with all of the information, allowing you to react when the first/primary call returns, and then again when the secondary/silver call returns, and so on, etc. Without the thunk you have to make a recursion loop to constantly check if an object to be hydrated is not null for each of the steps to emulate this effect.

.then versus .done versus .fail in the Promise API

When you chain on a .then it will take two arguments. The first is for a function for the success scenario and the second is for a function for the failing scenario. In contrast, .done just takes the success scenario argument and .fail just takes the failing scenario argument.

Saturday, November 3, 2018

I saw Scott Davis explain just how hard it is to secure a mobile game at the Twin Cities .NET User Group Thursday night.

This was a heavily negative talk, perhaps the most gloom-filled I've seen since this talk at Black Hat by Jennifer Granick, and we, the audience, were all warned upfront. Mr. Davis makes the mainstay of his living off of his mobile game QONQR which allows players to battle each other in local locale-specific environments (fight for control of Minneapolis if you live in Minneapolis not unlike being the mayor of the Olive Garden on Foursquare I guess) and has in-app purchases that players may make. Scott mentioned towards the end that he would not have tried to make his fortune in the mobile game space if he had once known what he knows now. As far as the geolocation stuff goes you cannot trust GPS. Comically, even though Android devices record a time from the applicable satellite, they end up replacing it with the device time before reporting it onward. A user may just fake GPS with a rooted Android device which is an Android device with a modified kernel. Beyond that one pain point however there are many more. Hackers are a demographic. There is an entire class of people who want to steal from you and the major players in the platform space are really more interested in providing security to consumers than to anyone developing for their platform. Apple doesn't want to even admit that it has security problems. Windows Phone 7 used to encrypt the packages that you publish as a downloadable from their store and with Windows Phone 8 Microsoft just took the encryption back away. Google has never encrypted the .apk packages that come down from something published to the American market store (or any of the multitude of stores in China's market) and anyone smart enough to rename an .apk to a .zip can have at your code. Therefore you will need to obfuscate your code which explains why Scott is pointing at a package named a in the photo here. (This was .NET talk. Unity did not have a map control of its own and the third-party map controls were Mickey Mouse when Scott started QONQR. This meant that Scott settled for Xamarin.) The obfuscation can only help you so much. If someone is stubborn enough they can reverse-engineer your code of course. The goal to settle for is to try to make things tough enough for thirteen-year-old kids in China following a YouTube movie to give up on hacking you and move on to an easier victim. Chinese hackers will try to download your application and reskin them as your own. They probably won't compete with you in the American marketplace because the Chinese marketplace is bigger and more lucrative. Naturally, one way to curtail this is roundtripping to the server-side of things for anything important be it the incrementing of in-game currency or your character's health-level I suppose. This makes it such that if anyone tries to pass off your work as their own they are still using your backend which they won't be able to just guess at and rewrite quickly on the fly. Beyond that you don't want things like in-game currency to be incrementable at the client anyways because someone could just hack the memory space holding the number on an Android device and make themselves rich. Someone could reskin your app, use your backend, and then use what is known as method hooking to find the applicable method for a trip to the server to make a payment (just search the code for something that has a name like "Transfer Balance") and splice in their own code there to give their account five dollars whenever a user uses the reskinned application to pass money on to you. Arxan.com is a not-too-affordable tool for preventing method hooking. There is no device-specific id on an iPhone. The device advertises an id that anyone may just reset by resetting the device so you cannot really block bad users based upon who they appear to be devicewise. SSL prevents man-in-the-middle attacks but at the end of a call a sinister individual can set up a proxy server with a fake certificate that doctors up requests and reencrypts them. I guess this environment could then pass through to your own environment in the case of a reskinned application that hits web services at the proxy server and then carries on to the legitimate backend. You may use something called SSL pinning to know if the SSL certificate is from an authoritative source. If you use open source software in your front end (John Sheehan's RestSharp which is an API tool was given as an example) unfortunately any hacker can just go pull the open source code, splice in their own logging, and then recompile a .dll that they use to replace the one that came down from the store and gain insights into what your code is up to. Your own home-rolled .dlls may be decompiled with Redgate .NET Reflector or Telerik JustDecompile so they may be hacked in kind. babelfor.NET was suggested to be a pretty good obfuscation tool. Amongst the things which normally make for good practices that get in the way of obfuscation are the S in the SOLID principles as if you keep things small and tight they can only be so misdirected and IoC. babelfor.NET will try to obfuscate public-facing interfaces in the IoC circumstance by giving the methods goofy names and giving you a map that does not get published to help you make sense of the gibberish and translate the obtuse to the sane while you are working on the code to ultimately be published in a different shape. The Android SafetyNet Attestation API can help you tell if a user is rooted. It is wise to have an incrementing number come back with each API call to your server. This helps tell if a user is really using the app and not just bouncing stuff off your API. Use BSON (binary JSON) in lieu of mere JSON. Use something like Captcha to prevent physical robots from using your application. Every if statement should have an else even if it seems like the else case can never be tripped. Put this in the else case:

if (System.Diagnostics.Debugger.IsAttached)
{
   System.Diagnostics.Debugger.Break();
}

 
 

Other things named-dropped include that an Azure worker role is a command line app that runs in Azure and that a NRUN is a non-repeating unique number. I hope I have that acronym right. Scott has put a lot of trial and error into figuring out how to prevent users fighting with other users. Basically there are four things you may do if someone makes you cranky in an exchange:

  1. report it
  2. ignore it
  3. block the user
  4. fire back

 
 

The problem with reporting users is that people go crazy with it. Scott introduced a way to appeal being reported and if you appeal and the reporting party is found to not have any real ammunition for getting you in trouble, they get in trouble twice as hard. This prevents an abuse of reporting.

f-strings in Python 3.6

...are basically like string interpolation in C# 6.0. Instead of the leading dollar sign before the opening double quote you have a lowercase f in Python. The f is for "formatted string literals" it seems.

OTP is one-time password

It's a password valid for one time / one session!

NVDA is a screen reader for the blind.

NonVisual Desktop Access is what the acronym unfolds to.

Webtrendz

...is a tool like Google Analytics for analytics.

Friday, November 2, 2018

XBRL is the eXtensible Business Reporting Language

EDGAR, the "Electronic Data Gathering, Analysis, and Retrieval" database of the SEC (U.S. Securities and Exchange Commission), takes in records in an XBRL format and public companies have to know how to get their records into XBRL to report to the SEC (or hire a consultant or consultancy to do it for them).

Thursday, November 1, 2018

AirDrop photos at modern iOS orchestrations.

On an iPhone 10 when you tap at the icon of a box with an arrow pointing skyward to send a photo you will see an AirDrop banner above the familiar message and mail icons. At least this is true with the version of iOS I have. I bought my iPhone 10 earlier this year and have not been the best about updating the iOS honestly. I’m not on version 12 as of yet. Anyways, this banner is pretty boring unless someone is holding their ear open to listen for airdropped photos, but if someone is listening you will see them at this banner and may push your photo into their photos library. To hold my ear open on my own phone, I drag down from the amount-of-battery-life symbol at the upper right and then press and hold in the dead space between four circles with icons (for airplane mode, cellular, Wi-Fi, and Bluetooth) that are in a box at the upper left together. This eventually opens up more options, one of them is AirDrop, and tapping that reveals options for Everyone to open up an ear and Receiving Off to close it again.

card trick interview question

An interview question that I recently botched had to do with sorting a deck of cards programmatically. Assuming we start with an array of 52 card objects in order and we want to end up with an array of 52 card objects in a random order, how should we do it? The best way is to make the sorted array a List<Card> in C# and then one by one randomly remove items from the list and add them to the slots of the end array. You could have a number in a loop incrementing down from 51 and that could both denote the slot in the shuffled array to fill and a range for a random number with which to grab a position from the list.

.charCodeAt is the way to get an ASCII character number off of a character in JavaScript.

See this and this.