Monday, July 31, 2017

July Queso

  1. TechCrunch has a bunch of tech news! TechCrunch Disrupt is a conference these guys put on. I only know about this from watching that Silicon Valley TV show.
  2. Midway Games which did Ms. Pac-Man is no more.
  3. www.visualstudio.com/vs/visual-studio-express has the Visual Studio Community Edition which does not require a license.
  4. IntelliJ IDEA is the IDE that JetBrains offers. Eclipse is a different Java IDE. NetBeans is a Java IDE too. One of the criticisms I've heard of the Java space is that there are too many ways to do things and this would an example of that.
  5. There used to be the concept of shadowing sessions in PC LANs. An administrator could watch the desktop of particular user without them knowing about it. This didn't really work because the victim's computer ended up running with a bunch of lag giving away that something was wrong.
  6. FoxPro (or perhaps Visual FoxPro) is some archaic language that is out of vogue. Its heyday was a dozen years ago. PHP survived Hurricane Katrina. This didn't.
  7. Marissa Mayer, the once CEO of Yahoo! which got bought by Verizon "Can you hear me now?" Communications, should probably really be remembered for Google Maps (and maybe Gmail). Before Google Maps everyone used MapQuest. Remember them? They have been bought out by Aol (formerly America Online) just like Netscape and are about as relevant anymore as is Netscape. The entire time I used MapQuest they never innovated. They were just kinda stale and stagnant.
  8. Carly Fiorina oversaw the buyout of Compaq when she was CEO of HP (Hewlett-Packard). Meh.
  9. I'm not going to do the surveys for Chili's or FedEx Office. Stop torturing your clientele with this stuff guys.
  10. Visual Studio Team Services has ways to share code and plan. You can manage scrum boards and Agile tools, etc.
  11. TMZ supposedly stands for thirty-mile zone in a reference to a bunch of Hollywood movie studios that are within a thirty mile expanse of LA (Los Angeles, California). It is some sort of celebrity gossip news organization and the term TMZ has become it's own animal in a more general sense vaguely conveying gossip and sleaze and the like.
  12. Hangfire looks to be a tool for "background processes" in .NET Core applications. Instead of having a windows service run what were referred to as cron jobs in FreeBSD gunk a dozen years ago (i.e. processes that get triggered at a specific time daily or weekly without a human pressing a button) or using Windows Task Scheduler you could, I suppose, use Hangfire now. I hear you may set it to ping an API endpoint X number of times before compensating... however it might... etc.
  13. Adobe InDesign is software for desktop publishing.
  14. Type "flip a coin" at Google to virtually flip a coin.
  15. Trellian SubmitWolf is a tool to register your web sites with search engines!
  16. The Go programming language of Google may be referred to as golang.
  17. If you were to graph my confidence whenever I'm looking for a job it would make a U shape. I start out really confident and obviously I'm back to being confident again when I finally get a job offer, but there is a dip in the middle. It basically takes me about a month to start working again once the floor falls out from under me. I haven't been out of work for two full months since 2002.
  18. I don't see any way to change the home page in Safari on my iPad. The true home page is just an empty browser pane. I just destroyed my history to make a sinister site that had been reappearing stop appearing when I opened the browser. The ability to do that is in the Settings for Safari. I'm using iOS 10.3.2 by the way.
  19. QWERTY is name for the standard way keys are laid out on a keyboard. It's named for the first six letters that appear left to right. The layout will supposedly make the most common letters the easiest to reach quickly. The Q, the most obscure English letter, for example, is only reached by moving one's left pinky upwards.
  20. "Elevated Mode" implies running Visual Studio 2017 as Administrator.
  21. You may pick songs or even one song and then make a Pandora station around them on Pandora. In doing so Pandora's algorithm will crawl outwards to find different things to recommend and it will suggest things for you to thumb up to keep to hear again. If you never thumb up anything it will keep finding new things in an attempt to placate you. Don't let it placate you. Dangle the carrot of affirmation just out of grasp of the codependent and have a laugh at its expense.
  22. webhookapp.com captures API requests for... I dunno... logging or the like I suspect.
  23. Google Play is something akin to Pandora or Spotify.
  24. cloudmailin.com turns inbound mail into POSTs to REST endpoints at your apps!
  25. Full Stack Developer as a term kinda implies someone who can work on the frontend and backend both of an application and all grey areas in between, database up to CSS styles.
  26. As of this month, Uber now has a way for you to tip through their app.
  27. Amazon Prime is a paid subscription that makes stuff on Amazon cheaper. It is one of those things that is only worth it depending upon how much you use it to get your money's worth. Prime Day is a day for deals to be had for Amazon Prime account holders, more deals than usual that it.
  28. In the JavaScript space... where there is no compiler safety... when you merge against someone else's rearrangement of an object that you need and end up with breaking changes... well, that is a rare example of a moment in which I actually crave the o of SoLID principles.
  29. dist is going to be short for distributed or distribution - In an app I'm working on there is a CI build process to build JS from TypeScript to a "dist" folder making "dist" files.
  30. nepotism is the practice of showing favoritism towards friends and loved ones and this materializes all the time in the tech sphere as people give jobs to people they know (In many ways this is not unfair if you think of the drought. There are is more work to be done in code than there are people who can write code so if you know someone who might be a fit for your open position they may not have any competition when interviewing. Are there even any other candidates to prefer your friend over? If not, are you even doing anything wrong by working every angle you can to fill a seat?)
  31. If you declare a bunch of characters like [-_+.a-zA-Z0-9]+ to maybe match in RegEx I kinda think the hyphen needs to go first. I have put the underscore before the hyphen before and it wasn't pretty.
  32. A skimmer attached to an ATM card reader at its "mouth" will pass on your credit card information while keeping it for itself.
  33. LINE is some app for free calls/messages.
  34. A punch card was a paper card full of holes that held instructions in programming up until the 1960s and vacuum tubes controlled the flow of electricity in 1940s and 1950s programming giving way to transistors around the time punch card fell out of fashion.
  35. Jelly is some thing wherein a bunch of people from different jobs get together in a common space and work side by side in the name of pseudooffice social butterflydom.
  36. Facebook now owns the Oculus.
  37. As best as I can tell, Cisco WebEx meeting will not show my name to others if I give a name with a space in it. No, that's not true. I also didn't work with the name TOMJAESCHKE even though CANYOUSEEMYNAME works.
  38. When database records contain bytes blobs for files and you "update" a file should you destroy the only record or just leave it orphaned, unassociated with the metadata at a different database table that loops it into the application?
  39. the Wayback Machine lives at: http://web.archive.org
  40. Maybe the word "please" should come out of validation error messages. These are really not options.
  41. Microsoft Planner ...is a planning application.
  42. Friendster was the thing like Myspace and Facebook before Myspace and Facebook.
  43. Discord is an app for mobile chat, like for two individuals who are gaming together with headsets in different homes.
  44. Twitch is now owned by Amazon.
  45. DbUpdateException is an explicit type of exception thrown by an Entity Framework DbContext in C#.
  46. You may use react.js in tandem with the new Angular! Redux (for JavaScript state management) and NGRX (for Angular-specific JavaScript state management) tie into that, I think.
  47. Best Buy credit cards come with a ridiculous interest rate of like twenty-four or twenty-five percent, but this rate is shelved for a few months on items actually purchased at Best Buy itself! There is a long window of no interest in these cases. (like six months)
  48. In a double-blind study both the testers and the tested do not know which drugs are real and which are sugar pills.
  49. While in-ear headphones get jammed deep into the ear like ear plugs, earbuds, in contrast, utilize the tragus and and other protusions around that waxy hole into your head to stay in place.
  50. The Iron Yard is a school that teaches people to code.
  51. A pick list is a grocery list of items to pull from your inventory for order fulfillment.
  52. A toaster component is going to give you popup messages.

sorting collections in TypeScript

whatever = whatever.sort((yin, yang) => {
   if (yin.label > yang.label){
      return 1;
   }
   if (yin.label < yang.label){
      return -1;
   }
   return 0;
});

Sunday, July 30, 2017

some notes on the template-driven approach to forms in Angular 4 applications

  1. This is the alternative to reactive forms.
  2. <form action="/action_page.php" method="post"
       enctype="application/x-www-form-urlencoded">
    is an old school example of a form tag. None of these inline settings will be present in a form tag at a template-driven form.
  3. import { FormsModules } from '@angular/forms'; needs to go at the top of the module wrapping a component that will use a template-driven form and the module needs to spec FormsModules at imports.
  4. Each element inside a form must be registered. Give the tags name attribute settings and put ngModel inline at any one element, perhaps with no banana box around it.
  5. <form (ngSubmit)="onWhatever(f)" #f>
    ...is an example of a form tag that would trigger the onWhatever event when a button within it that was of type="submit" was clicked. On the TypeScript side you could loop in this...
    import { ElementRef } from '@angular/core';
    ...and then have some sort of something like this...
    onWhatever(myObject: ElementRef): void {
    ...however the ElementRef here may prove frustrating to work with. A suggested revamp of this is:
    <form (ngSubmit)="onWhatever(f)" #f="ngForm">
    ...and...
    import { NgForm } from '@angular/forms';
    ...and, yes...
    onWhatever(myObject: NgForm): void {
    ...allowing one to inspect myObject.value to see key/value pairs for the form fields designated. The name attributes hydrate the keys.
  6. myObject.controls will have an object wherein each of the parameters holds a FormControl for each registered element. A FormControl will have more details, like dirty, etc.
  7. @ViewChild('f') myObject: NgForm; as a variable in a component would be another way to have at the local reference if you didn't want to pass it in ngSubmit
  8. putting required inline at an input tag will allow for some validation in the template-driven paradigm and putting email beside it furthermore validates for an email address ...This ends up changing the true or false state of the valid setting of the given FormControl and also the valid setting overall at the form, big picture. Classes like ng-dirty, ng-touched, and ng-valid get conditionally applies to form controls and, as you might guess, ng-invalid shows up when ng-valid does not. You can have a [disabled] on the form button based on if the whole of the form is valid, and a bunch of other similar tricks based on this stuff.
  9. Putting a local reference like #foo="ngModel" inline at an input tag allows for help blocks like so to appear when one screws up what one puts in the form field:
    <span class="help-block">Yikes!</span>
    ...and herein help-block is a Bootstrap class for this sort of thing.
  10. At an input changing ngModel to [ngModel]="whatever" will allow for one-way data binding and set a default value based on whatever is in the whatever variable as defined back at the TypeScript side of things. Banana box two-way databinding with something like [(ngModel)]="whatever" would allow whatever to be displayed elsewhere on the form as a magic string and it would get updated real time as the user types in the input with the two-way data binding.

temp token

Kinda like the bearer-token here, this is instead session-based. Whenever you log in a row is created in a database table and the GUID for the unique key is given to you. You use it for all API calls downstream. The row at the database is destroyed by an automated process after fifteen minutes. You will want to double authenticate with another piece of data, probably a bearer-token which will be kept at the database row.

Saturday, July 29, 2017

notes from some online trainings on Observables

  1. http://reactivex.io/rxjs/ has the RxJS documentation. Pick "Observable" from the menu at the left and scroll down to see all of the operators! Just have up top import 'rxjs/Rx'; at your component to let the operators be accessible.
  2. import { Subject } from 'rxjs/Subject';
    export class PezDispenser() {
       dispensePez = new Subject();
    }
    ...is an example of using Subject out of the RxJS stuff, or perhaps more appropriately, an example of the cornerstone of the example as what is above by itself does not yet show off using it. I named this service PezDispenser as these kinda behave like Pez Dispensers, well, if Pez Dispensers had some state swappablity going on. I'll get to what I mean in a moment, but more simplistically we may get a piece of candy from our Pez Dispenser by looping it in as a service in a component and then tapping its head like so:
    onTap(): void {
       this.pezDispenser.dispensePez.subscribe(
          (pez: Pez) => {
             alert(pez.flavor);
          }
       );
    }

    I think if you call what is above first without setting what type of candy the PezDispenser will spit out that this will blow up and you'll get a nasty red message in the Google Chrome console about how flavor of undefined cannot be resolved. Then again, for all I know, this process will just hang out until the type of candy is set and the PezDispenser can actually dispense. That takes us to a second caveat. You will want to have an ngOnDestroy implementation at your component to unsubscribe for things like this to avoid memory leaks. You may set the type of Pez, perhaps from a second component, using the service as a middleman state machine for messaging between two components, like so:
    setFizzy(): void {
       let pez = new Pez();
       pez.flavor = "Fizzy";
       this.pezDispenser.dispensePez.next(pez);
    }

    Alright, that makes for an end to end example and yet there is nothing interesting about this without the swappable state stuff I eluded to earlier. Indeed, you don't even need a service or RxJS if you want to consistently give Pez that is Fizzy in flavor from your dispenser. The thing that makes this interesting, and you can probably see it already, is that you may set the Pez candies to be of a different variety like so:
    setPeppermintSugarFree(): void {
       let pez = new Pez();
       pez.flavor = "Peppermint Sugar-free";
       this.pezDispenser.dispensePez.next(pez);
    }

    For the other party (component) tapping the head, there is a what-will-I-get mystery akin to that of Erwin Schrödinger's cat in that you may either get candy that tastes like dead cat or candy that tastes like live cat and there is no way to know until you do.
  3. .map(
       (digit:number) => {
          return digit + 13;
       }
    );
    ...is, of course, an example of the .map operator. Duh.
  4. BehaviorSubject is like Subject only it starts with a default beginning placeholder setting.

Friday, July 28, 2017

making sure a parent's initialization lifecycle hook is called from a child component in Angular 2

Use an ngOnInit in this way to call a parent's ngOnInit from a child component which will otherwise not go off if the child component has an ngOnInit.

ngOnInit():void {
   super.ngOnInit();
   childishStuff();
}

 
 

Removing the child's ngOnInit would also be another way to get the parent's ngOnInit to fire off, but then you couldn't do childishStuff();

Thursday, July 27, 2017

How do I pass both a POCO and a file to a Microsoft.AspNetCore.Mvc.Controller at once?

It turns out this is modestly challenging and unintuitive and that you cannot really pass an object at the method signature of the action catching stuff if you are catching a file too in this manner. Instead try something like so:

[HttpPut]
[Route("api/widget/{keyId}")]
public bool UpdateWidgetWithInstructionManual(long keyId)
{
   HttpRequest request = this.Request;
   IFormFile file = request.Form.Files[0];
   string serializedWidget = request.Form.Keys.ToList()[0];
   serializedWidget = serializedWidget.Replace("%22", "\"");
   Widget widget = JsonConvert.DeserializeObject<Widget>(serializedWidget);
   var fileName = file.FileName;
   var fileContentType = file.ContentType;
   var fileData = default(byte[]);
   using (var reader = new StreamReader(file.OpenReadStream()))
   {
      using (var memoryStream = new MemoryStream())
      {
         var buffer = new byte[file.Length];
         var bytesRead = default(int);
         while ((bytesRead = reader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
         {
            memoryStream.Write(buffer, 0, bytesRead);
         }
         fileData = memoryStream.ToArray();
      }
   }
   _myStaticStuff.Act(fileName, file.Length, fileContentType, fileData, widget, keyId,
         _widgetRepository);
   return true;
}

 
 

I am deferring saving the stuff I collect to a database in the third to last line above by calling another method. The signature for as much would look like so:

public static void Act(string fileName, long fileLength, string fileContentType, byte[]
      fileData, Widget widget, long keyId, WidgetRepository widgetRepository)
{

 
 

What does this do? Well, you can use your imagination. The point of this exercise is not really to show the savings of a bytes array to a database, but instead to exhibit taking in both an object and a file at a controller action. This does beg the question of how does one hand off to the action to begin with. In TypeScript in an Angular 2 application you would have to have some magic like this wherein this.http is an Http looped in from @angular/http as an import. Note: no options! Headers seem to sabotage things.

public updateWidgetWithInstructionManual(widget: any, keyId: number, file: any): void {
   let url = "http://www.example.com/api/widget/";
   let formData:FormData = new FormData();
   formData.append('uploadFile', file, file.name);
   formData.append(JSON.stringify(widget), 'widget');
   this.http.put(url + keyId, formData, {headers:{}})
         .toPromise()
         .then(function(data){
            console.log('success');
         },function(error){
            console.log(error);
         });
}

WeakMap

A WeakMap is distinguishable from a map in both JavaScript and TypeScript by way of the fact that it is explicitly instantiated as a WeakMap, perhaps like so:

var weakSause = WeakMap();

 
 

The line items in a WeakMap are vulnerable to being cleaned up by garbage collection if they are unused and this is both the strength and the weakness of a WeakMap and also the distinction between a Set and a WeakSet as well. (The sets let you store a collection of things as long as each thing is unique.) Why would you want to do this? The reason to go there is if you have a dictionary that can grow fat overtime due to you pumping a bunch of gunk into it and never cleaning it up. What if you cause a memory leak?

When you lose the ability to drag and drop files at Slack for Windows...

Reinstall! By the way, you can always click on that plus sign to the left of where you type and pick "Your computer" to browse for a file too.

return this; (in C#)

In a method, at its end, this will return the instance of the class as an object! This comes up in:

  1. prepping some not so anemic state
  2. turning around and using the state

TS2345:Argument of type 'string' is not assignable to parameter of type 'RegExp'.

The problem with the following code is that it does not use two strings. One of the variables is of the wrong type.

let liar = 13;
let billiards = 'billiards';
let whatever = billiards.replace('liar', liar);

Wednesday, July 26, 2017

maps in TypeScript (think dictionary)

What follows is stolen from here and I don't really know if it is quite exactly an example of a Map or a WeakMap as of yet. Assume this is a public variable in an Angular 2 component:

public fileMap: {[key:number]: any};

 
 

Add stuff like this:

addItem(id:number, file:any): void {
   if (!this.fileMap) this.fileMap = {};
   this.fileMap[id] = file;
}

 
 

Get stuff back out like this:

getFileThirteen(): void {
   if (!this.fileMap) this.fileMap = {};
   let fileThirteen = this.fileMap[13];
   return fileThirteen;
}

 
 

If item 13 isn't there, undefined will be returned above.

Tuesday, July 25, 2017

when you screw up a commit in Atlassian SourceTree with a bunch of bad merges...

Find the last good commit and right-click on it and pick "Branch..." to just make a new branch. That will be less painful than trying to revert changes honestly. The "Specified commit" should be selected by default in this approach.

TS2341:Property 'input' is private and only accessible with class 'Typeahead'.

This isn't true at all! If you have a Typeahead with a local reference of #whatever in an Angular 2 app then...

let input = this.whatever.input;

 
 

...in TypeScript lets you have at the setting. Don't be fooled by this tooltip.

 
 

Addendum 7/28/2017: It is better to use let input = this.whatever.value.text; for something like this as it turns out as the code above (which seems to work in spite of making TypeScript cranky) will not compile in build-to-dist-file scenarios. I spoke too soon!

 
 

Addendum 12/7/2018: A typeahead is like an autocomplete.

visibility:hidden; versus display:none;

As far as CSS styles go, display:none; completely acts as though the element styled with it isn't there but visibility:hidden; unfortunately creates a blank dead space in the shape of the missing element. Lame.

My .edmx is missing some tables! What do I do?

Well, things have probably changed at the Database itself. You need to update the Entity Framework .edmx whenever the database changes for new tables to be accessible at your DbContext. Open up the goofy GUI interface for the .edmx by just double-clicking the .edmx in Visual Studio 2015 and then right-click in some of the dead white space and pick "Update Model from Database..." from the options that appear. You may find that the .edmx and supporting files have all of their tables updated when you only wanted to loop a new table in. If you want you may cherry pick what is to be kept from a greater looping in by selecting the files in Atlassian SourceTree (at staged and unstaged files) and then picking "Discard hunk" here and there to toss away unwanted sections of green. (additions)

when a number appears next to a channel in Slack and you don't have any unread messages...

Well, maybe you dropped a pin. Look at "Pinned Items" at the upper right and see you can unpin the thing you pinned.

 
 

Addendum 8/22/2017: Another thing that can cause this problem is a blue ribbon with a notification overlaying the chat details at the very top. It will have an X you may click to make it go away. The pain point is in and of the overarching framework and does not come from your accidents.

How to make a hidden input type field in the Angular 2 paradigm.

DO: Put the hidden value, in this case theId, in the FormGroup!

this.v = new FormGroup({
   'myControl': new FormControl(''),
   'somethingElse': new FormControl(''),
   'theId': new FormControl('')
});
this.v.patchValue({
   'myControl': this.foo.bar,
   'somethingElse': this.foo.baz,
   'theId': this.foo.qux
});

 
 

DO NOT: Literally make an HTML control for the hidden value. In this case there is no control for theId.

<form [fromGroup]="v">
   <input type="text" formControlName="myControl">
   <br />
   <input type="text" formControlName="somethingElse">
   <br />
   <button (click)="makeMagic(v)">Go</button>
</form>

Saturday, July 22, 2017

Observable ABCs in the abstract

I am just over halfway through a series of online trainings on Angular 4 and it is starting to get into Observables. Today I learned some stuff so simple that there isn't really a praxis for it. Consider these imports:

import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { Observer } from 'rxjs/Observer';

 
 

They will allow you to do something silly like this which will sequentially show you numbers counting up at the console:

const whatever = Observable.interval(1000);
whatever.subscribe(
   (numb: number) => {
      console.log(numb);
   }
)

 
 

Honestly, we didn't need Observer for what was immediately above, but let's loop that in now.

const fly = Observable.create((flyFu: Observer<string>) => {
   setTimeout(() => {
      flyFu.next('our fly is still alive after one second');
   }, 1000);
   setTimeout(() => {
      flyFu.next('our fly is yet still alive after two seconds');
   }, 2000);
   setTimeout(() => {
      flyFu.error('our fly has died');
   }, 3000);
});

 
 

Observer, which I had never heard of, lets me fake an asynchronous call against maybe a web socket as I never would. Yay! This naturally allows for:

fly.subscribe(
   (yes: string) => {
      console.log(yes);
   },
   (no: string) => {
      console.log(no);
   },
   () => {
      console.log('our fly is done');
   }
);

 
 

The three cases above are of course:

  1. getting something back from an Observer successfully
  2. an error handling scenario
  3. something to happen upon completion

 
 

...in that order. You will never see the completed scenario in running our code above. In order for that to happen the error jammed in a setTimeout would need to perhaps be changed up like so:

setTimeout(() => {
   flyFu.complete();
}, 3000);

 
 

Once the complete goes off there will be no further asynchronous activity. Expect no new successes or errors.

Friday, July 21, 2017

I hate the template tag in Angular 2.

<template ngFor let-foo [ngForOf]="stuff" let i="index">

...is vaguely like...

<ng-container *ngFor="let foo of stuff; let i=index">

See if an array of strings contains one string in particular in JavaScript!

var stuff = ["foo", "bar", "baz", "qux"];
if(stuff.indexOf("bar") > -1){

window.scrollTo(0,0);

I guess this JavaScript is to move the scrollbars leftmost and topmost at the browser.

Wednesday, July 19, 2017

when publishing from Visual Studio 2015 and you want to change the username

  1. To publish, right-click on the startup project and pick "Publish..." at the Solution Explorer.
  2. By the time you see the "Web Deploy Client" dialog where you enter a password, it is too late to doctor up the username after the fact in spite of the fact that it appears that you may.

Instead between steps 1 and 2 above when you are at the Publish dialog box and you see...

  • Profile
  • Connection
  • Settings
  • Preview

...at the upper left, click on "Connection" to change the username.

when you remote desktop (Microsoft Terminal Services Client) into Windows Server 2008 R2 and the desktop is just black

click Ctrl-Alt-End which is akin to doing Ctrl-Alt-Delete at the server (obviously you cannot just do Ctrl-Alt-Delete as it would apply to your own PC) Next, press "Cancel" which will solve your problem.

Tuesday, July 18, 2017

import {Http} from '@angular/http'; ...cannot fire and forget

You are going to have to hand back something like true or some other vapid placebo value from PUT and DELETE endpoints when using this Angular 2 means for AJAX and you cannot just have an endpoint that returns void. The only way I can see to get around this, should you not control the API you are consuming, is to wrap the Http implementation in a try/catch where the exception is swallowed so that when it blows up you do not see red at the console. Your endpoint (returning void) will still get hit.

try{
   this.myHttpInstance.put(myUrl, {}, myOptions).toPromise();
}
catch(exception){
}

Did you know that if you snug up the contents of a div with display:inline-block; that it will not wrap floating items inside?

I'm serious! The outermost div below ends up being one hundred pixels wide! This is legit in both Chrome and IE. The div with "foo" and the div with "bar" sit side by side!

<div style="height:20px; display: inline-block;">
   <div style="height:20px; width:50px; float:right;">foo</div>
   <div style="height:20px; width:50px; float:right;">bar</div>
</div>

if(myCollection.length===0){ versus if(!myCollection.length){

if(myCollection.length > 0){ versus if(myCollection.length){ would be the duel for the opposite JavaScript scenario I suppose. Which is best? Should you be idiomatic or explicit? At lunch today I asked coworkers what they thought and they agreed that idiomatic is ideal. It is certainly alright to do a truthy or falsey check around the length of an array.

a better posting on getting Observables back out of Observable shapes on the TypeScript side so that you may do stuff with them

In order to force an Observable to a .toPromise() like this some stuff has to happen upstream. In your service where you make a rest call, craft something like so:

public findFoo(matchManyGuid: string): Observable<Array<MyDto>> {
   var url = "http://www.example.com/api/foo/" + matchManyGuid;
   return this.http.get(url).map(response => this.mildParsing(response));
}

 
 

Alright, we need ._body off the Response and for some reason I don't yet understand we cannot have at it with type safety in the way so we have to have a hack like this to cast a Response to an any.

protected mildParsing(r:any) {
   let parsing = JSON.parse(r._body, function(key,value){
      return value;
   });
   return parsing;
}

 
 

Finally, get what you want where you call the service:

this.myService.findFoo(someGuid).toPromise()
   .then(function(data){
      let foo: Array<MyDto> = data;
      console.log(foo);
   },function(error){
      console.log(error);
   });

Monday, July 17, 2017

a hack to make a (click) event behave like a hyperlink in the Angular 2 space

An a tag like this with both a href setting and a click event can behave well without any help from CSS styling.

<a href="#" (click)="doWhatever()">touch me</a>

 
 

You will need to make the click event itself return false so that the tag does not actually redirect away anywhere when clicked.

doWhatever():boolean{
   alert('whatever');
   return false;
}

Ciphers don't have to be consistent.

That's a challenge. In a one way hashing, say for passwords, the hashing is going to be consistent as you will want to compare a possible answer for a password, after a hashing, to the hashed value for a password at a database. If a different data point is merely encrypted, say a social security number, well that is a different thing. 457-55-5462 could look like two different things when encrypted as the cipher to dencrypt can handle as much, but this shape of things, a shape never intended to do the hash comparisonesque comparisons comes with some challenges. What if you want to grab a record by a SSN? You will have to query all the records, perhaps dumbing the records down to just id and SSNs alone, and then loop through the records doing an unscrambling before finally fishing for what you need in the in-memory table.

more than you ever wanted to know about Angular 4 routing

  1. Picking back up from bullet point nine here, I can fish back out the id like so at an Angular 4 component:
    let id = this.whereAmI.snapshot.params['id'];
    This will require some wire up. Firstly like so:
    import { ActivatedRoute } from '@angular/router';
    ...and, yes, there is a second step:
    constructor(private whereAmI: ActivatedRoute){}
  2. The trick above will not work if you are in the component with the id already. It will work when you navigate there, but then when you manually change the id at the url line or click a link that forces the id to change the component will not update as Angular will refuse to reload components willy-nilly. To get around this chase ActivatedRoute with ,Params at the import statement and then do something like so:
    this.whereAmI.params.subscribe(
       (gunk: Params) => {
          this.idNow = gunk['id'];
       }
    );
  3. Alright, the params thing above is an example of a subscription that will get destroyed when the component is also destroyed, but this isn't always the case. There will be plenty of times when a subscription will not die in such a circumstance and you must do the work to kill it. (Don't let it linger.) For starters, in those cases, you'll need this import:
    import { Subscription } from 'rxjs/Subscription';
    Moreover, the component needs to implement the OnDestroy lifecycle hook and declare a Subscription variable somewhere in the component outside of the methods (not in a method) so that the variable is available component-wide. Let's call our variable Foo, alright? When we start the subscription we would need to assign it to Foo like so:
    this.Foo = this.whereAmI.params.subscribe(
       (gunk: Params) => {
          this.idNow = gunk['id'];
       }
    );

    Again, this use case is really not a use case wherein we need to undertake this headache, but it ironically also won't hurt. Anyhow, long story short, we destroy the subscription like this:
    ngOnDestroy(){
       this.Foo.unsubscribe();
    }
  4. How do I add the url line variables separated by ampersands with a leading question mark and the hashtag/numbers symbol/pound sign led setting for a named anchor which was once upon the time used for midpage links that were not supposed to reload the page and evoke another round trip to the server? Alrightly, let's suppose our url is to be http://www.example.com/whatever/blossom?bar=bubbles&baz=buttercup#qux assuming a route with a path of 'whatever/:foo' which would mean that an a tag with [routerLink]="['/whatever','blossom']" in its guts would also get [queryParams]="{bar: 'bubbles', baz: 'buttercup'}" and [fragment]="qux" in its guts at a template. At the TypeScript side this looks like:
    this.myRouter.navigate(['/whatever','blossom'], {queryParams:
       {
          bar: 'bubbles',
          baz: 'buttercup'
       }
    }, fragment: 'qux');
  5. fish this stuff back out with this.whereAmI.snapshot.queryParams, this.whereAmI.snapshot.fragment, this.whereAmI.queryParams.subscribe(), and this.whereAmI.fragment.subscribe()
  6. All of the variables pulled out of params, queryParams, and fragment are going to be strings. You must cast them to other types if you need other types. Did you know that you may just use + in lieu of <number> for casting to a number?
  7. There is a way to have a cascading effect with nested routes so that the components summoned into the <router-outlet></router-outlet> tag may have <router-outlet></router-outlet> tags of their own wherein a nested component within the nested component may vary based on the URL. That looks like this:
    const myRoutes = [
       {path: '', component: StartingOutComponent},
       {path: 'animal', component: AnimalComponent, children: [
          {path 'bat', component: BatComponent},
          {path 'cat', component: CatComponent},
          {path 'rat', component: RatComponent}
       ]}
    ];

    The URLs for the five items above might be http://www.example.com/ and http://www.example.com/animal and http://www.example.com/animal/bat and http://www.example.com/animal/cat and http://www.example.com/animal/rat in that order.
  8. this.myRouter.navigate(['/yin','yang'], {queryParamsHandling: 'preserve'}); will preserve your query parameters as you navigate away and this.myRouter.navigate(['/yin','yang'], {queryParamsHandling: 'merge'}); will mix them in with the other parameters to come where you land.
  9. {path:'biscuit', redirectTo:'/muffin'} is a way to make one route fall over to another and if you have {path:'**', redirectTo:'/muffin'} as your very last route all routes that can't be found will get redirected to the route speced.
  10. As your routing grows fat, it's a good idea to pull it out of the godmost wrapper module gateway into everything and give it its own module. By convention this will be called AppRoutingModule and will live in a file named app-routing-module.ts and you will need to have RouterModule as one of the exports in this new module and you will need to have AppRoutingModule as an import in your highfalutin boss module enveloping the rest of the app.
  11. Alight, you may protect a route from access from the unauthorized by putting canActivate: [AuthGuard] in line in a route and this in turn will reference a file that very specifically should by convention live in a TypeScript file called specifically auth-guard.service.ts. AuthGuard, a service, and another sister service for actually making database calls to see if the user at hand is authenticated (let's call it WhateverService) are going to need to be looped in as services at the outermost module as variables at the constructor, etc. WhateverService will vary from app to app but AuthGuard should really be something pretty specific. The bullet points so far have all been stuff I've picked up in watching a series of online trainings and I've been trying to reshape what I learn before I regurgitate it to you in the name of not being guilty of plagiarism, but AuthGuard needs to be so specific that what follows is just outright stolen from elsewhere. Can you guess where? Anyhow this is what the most simple skeleton for AuthGuard should look like before you loop in code specific to the WhateverService such as, of course, looping it in as a variable at the constructor signature.
    import {
       CanActivate,
       ActivatedRouteSnapshot,
       RouterStateSnapshot
    } from '@angular/router';
    @Injectable()
    import { Observable } from 'rxjs/Observable';
    export class AuthGuard implements CanActivate {
       canActivate(route: ActivatedRouteSnapshot, state RouterStateSnapshot):
             Observable<boolean> | Promise<boolean> | boolean {
       }
    }

    Alright, you have to have the canActivate if you implement CanActivate and it should return something even though we don't see it do so above. Well, it should return something based on what WhateverService hands back from a request like so:
    isAuthenticated() {
       const promise = new Promise(
          (resolve, reject) => {
             setTimeout(() => {
                resolve(this.loggedIn);
             }, 800);
          }
       };
       return promise;
    }

    canActivate is gonna hand back this.router.navigate(['/']); ultimately to deny someone or true; to let them through.
  12. There is a way to allow anyone to see a route but to wall off that route's child routes behind maybe-we'll-let-you-in security. The trick, specificially, is to use canActivateChild: [AuthGuard] instead of canActivate: [AuthGuard] (the setting still goes at the parent route), and all you have to do to set that up is to refactor the AuthGuard skeleton for route guards like so:
    import {
       CanActivate,
       CanActivateChild,
       ActivatedRouteSnapshot,
       RouterStateSnapshot
    } from '@angular/router';
    @Injectable()
    import { Observable } from 'rxjs/Observable';
    export class AuthGuard implements CanActivate, CanActivateChild {
       canActivate(route: ActivatedRouteSnapshot, state RouterStateSnapshot):
             Observable<boolean> | Promise<boolean> | boolean {
       }
       canActivateChild(route: ActivatedRouteSnapshot, state RouterStateSnapshot):
             Observable<boolean> | Promise<boolean> | boolean {
          return this.canActivate(route, state);
       }
    }

    Again, this is just a skeleton. This will not work as long as the canActivate method returns nothing. The thing this does not show yet is your own code for cross talking with another service yet that talks to your database and finds out if Alice and Bob are active users. Once more, either a rerouting or just true will be returned and there is much wiggle room for how it may be returned. It could just be returned outright or it may come back as part of an observable or a promise. In the case of a promise you would be catching the promise and then doing a .then to have at what will happen when the promise resolves.
  13. There is a way to do a CanDeactivate to give users "Are you sure?" messages when they attempt to leave a route. You do that with code like so:
    import { Observable } from 'rxjs/Observable';
    import { CanDeactivate } from '@angular/router';
    import { MyInterface } from './my-interface.ts';
    export class MyGuard implements CanDeactivate<MyInterface> {
       canDeactivate(component: MyInterface,
             currentRoute: ActivatedRouteSnapshot,
             currentState: RouterStateSnapshot,
             nextState?: RouterStateSnapshot): Observable<boolean> |
                   Promise<boolean> | boolean {
          return component.leavingSoSoon();
       }
    }

    You'll need to make a file for the interface suggested too:

    import { Observable } from 'rxjs/Observable';
    export interface MyInterface {
       leavingSoSoon: () => Observable<boolean> | Promise<boolean> | boolean;
    }

    Alright, in order to make this stuff work you put a canDeactivate inline at the route and the component that uses it must implement the interface specified, I guess MyInterface in this case. This will force the component to have a leavingSoSoon method inside of it like this:
    leavingSoSoon(): Observable<boolean> | Promise<boolean> | boolean {
       return confirm('Leaving so soon?');
    }
  14. You may jam little messages inline in a route by putting data: {talky: 'I am talking.'} or something similar inline in a route and then pull this content back out with:
    let x = this.whereAmI.snapshot.data['talky'];
    and...
    this.y = this.whereAmI.data.subscribe(
       (gunk: Data) => {
          this.z = gunk['talky'];
       }
    );
  15. resolver: {talky: MyResolver} will behave like the data setting but will, in a roundabout way, take one of the other route params or queryParms or fragments and find a friendly message for it which will be fished out the same manner as suggested in the bullet above. You'll need an interface:

    interface MyMessagingObject {
       id: number,
       name: string,
       status: string
    }

    It gets used by something like so which has to be looped in at the providers of the outermost module:
    import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot }
          from '@angular/router';
    import { Observable } from 'rxjs/Observable';
    import { MyMessagingObject } from './my-messaging-object.ts';
    export class MyResolver implements Resolve<MyMessagingObject> {
       resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
             Observable<MyMessagingObject> | Promise<MyMessagingObject> |
             MyMessagingObject {
       }
    }

    Again I am showing a skeleton here. The resolve route has to return something. I recommend doing a dot dot dot off of "route" to get the parameter you need and then to go fishing with it to look up from another service whatever you need to fill out MyMessagingObject which you will ultimately get back instead of a mere string.

  16. RouterModule.forRoot(myRoutes, {useHash: true}) as a slight change up from the other stuff at the link at the top of these bullets lets us have routes with a hastag in the middle of them such as http://www.example.com/#/whatever and you really only want to do this if you are accomodating some really old browser. It is possible that the routing won't work without this hack.

Saturday, July 15, 2017

I like Freebirds better than Chipotle.

Chipotle doesn't even have jalapeños on its bar. That just seems backwards to me. A coworker has pointed out to me that Chipotle is a national chain while Freebirds isn't and that therefore they are not going to across the board roll out jalapeños universally which only part of the country (Texas) is gonna embrace. Freebirds is more of Texas thing. I think its Texas footprint has gotten bigger than its California footprint anymore. It is closer in keeping to what I expect.

 
 

Addendum 7/16/2017: I went by Chipotle today to reaffirm my expectations. It was pretty good honestly. One thing that was really backwards was that I could not tip with my credit card and I did not have any cash on me (who carries cash?) so I just did not tip. I again suspect this is a trapping of a big corporate nationwide behemoth.

Friday, July 14, 2017

I don't want users to have to explicitly allow pop-ups in Google Chrome to be able to download a file I present from JavaScript.

Grrr. Pesky pop-up blocker! It's not that hard to sidestep as it turns out. This...

window.open("http://www.example.com/cat.jpg");

 
 

...just needs to become this:

window.open("http://www.example.com/cat.jpg", '_blank');

Thursday, July 13, 2017

It may at times be wise to cast a FormGroup to an any in TypeScript and Angular 2 before doing a dot dot dot out past the controls on it.

Typing out something hanging off .controls will work when you just run the app standalone most likely, but if something actually does sanity checking with the compiler such as a Webpack CI process you are in trouble.

let altF: any = <any>this.f;
let whatever: string = altF.controls.Person.controls.LastName.value;

Ctrl-Click in WebStorm 2017.1.2

This will allow you to drill into a method in a manner akin to "Go To Declaration" either in WebStorm or Visual Studio. If there is more than one applicable option for some reason you will get a ReSharperesque set of choices. Also after you have dived in, you have dive back out by doing Ctrl-Click again!

Clippy lives!

When I attempt to put [disabled]="whatever" inline at an input tag in an Angular 2 rective form and then run my application not only does the trick not work, but this makes its way up to the console to boot:

It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true when you set up this control in your component class, the disabled attribute will actually be set in the DOM for you. We recommend using this approach to avoid 'changed after checked' errors.
 
Example:
form = new FormGroup({
   first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
   last: new FormControl('Drew', Validators.required)
});

 
 

That said, I tried to do things Clippy's looks-like-you're-trying-to way and it didn't work either. At the moment I am just dealing with the problem like this:

<ng-container *ngIf="!whatever">
   <input type="text" formControlName="Foo">
</ng-container>
<ng-container *ngIf="whatever">
   {{stuff.Foo}}
</ng-container>

the dirty flag at a FormGroup itself in Angular 2

Alright, obviously the FormGroup controls have a .dirty flag, but did you know that an instance of FormGroup itself has a .dirty flag? Cool stuff.

Wednesday, July 12, 2017

Use .patchValue with a FormGroup in Angular 2!

This is a way to add setup values to a FormGroup after you've set it up. They could come from data loaded from a service. In the example below I'm just jamming them in.

this.myFormGroup.patchValue({
   'Yin': "Vicky",
   'Yang': "Christina"
});

 
 

This will put "Vicky" in the Yin control and "Christina" in the Yang control and it doesn't really matter where in the FormControl Yin and Yang are. They seem to get found even if they are nested in a FromGroup within the FormGroup.

How to create validation error messages in the Angular 2 Dynamic Forms paradigm.

In conflict to what I say here due to my learning a bit more, there is a way to do traditional validation messages with angry red messages unhiding when someone fills out a form field the wrong way. Alright, if FooGroup is a FormGroup with a FromGroup named BarGroup inside of it and BarGroup moreover has a control called Celly, you could dot dot dot out to Celly's setting like so:

alert(FooGroup.controls.Person.controls.Celly.value);

 
 

Celly, as a control also conveniently has a flag to let you know if its value has changed up. It's called dirty and dirty is true if the user has changed the value from what it was and false if not. Behold:

if(FooGroup.controls.Person.controls.Celly.dirty){    alert(FooGroup.controls.Person.controls.Celly.value);
}

 
 

Now for the good part! There is also a setting called .valid and it is also true or false and it does what we need.

<input type="text" class="typeInMe" formControlName="Celly">
<div [hidden]="FooGroup.controls.Person.controls.Celly.valid" class="youFool">
   That's not a phone number junior!
</div>

no "Exclude From Project" in .NET Core implementations

There is no .csproj file governing which files are looped into the project. Instead, everything is looped in. (yee-haw)

How do I open an .edmx from Visual Studio 2015's Solution Explorer as XML and not in the WYSIWYG editor?

You cannot just double-click the filename. That gives the WYSIWYG tooling. Instead right-click on the .edmx in the Solution Explorer and pick "Open With..." which will give you some options. You can probably just pick "XML (Text) Editor" here to you get what you want. The option for "ADO.NET Entity Data Model Designer (Default)" in contrast gives the WYSIWYG (what you see is what you get) GUI tooling.

Tuesday, July 11, 2017

a NavigationProperty at an .edmx

These kinda look like this if you look at the XML for the .edmx itself.

<NavigationProperty Name="BillingAddress"
      Relationship="MyModel.FK_Person_Address_Billing" FromRole="Person"
      ToRole="Address" />

 
 

Imagine if you will that we have a database table for Person and a database table for Address and that that the Person table has two nullable GUID columns for MailingId and BillingId that correspond to Address records. The above markup sort of manages the billing address relationship and allows one to dot dot dot out to an adjacent concept, if you will, with LINQ queries like so:

Place = new Locale()
{
   Name = p.BillingId == null ? null : p.BillingAddress.City
}

 
 

Clearly p above is the queried Person table but instead of the bridge pseudoobject being named Address or BillingId it's name can be kinda funny, in this case: BillingAddress

Monday, July 10, 2017

How do I crop an image I rotated as a background with CSS so that it again has clean vertical edges and clean horizontal edges?

Great question. Let's start off with this:

<div style="width:540px; height: 400px; background-image:
      url('https://68.media.tumblr.com/84f731e1b7c9ce8a81786f29b36762fc/
      tumblr_os45hx7DZw1vk5zz2o5_540.jpg');">
</div>

 
 

It's going to give us this tumblr image of Eiza González Reyna. I'll use her as my muse. She is on my mind because I just saw her in the film "Baby Driver" last night.

 
 

Now let's rotate the image like so:

<div style="width:540px; height: 400px; background-image:
      url('https://68.media.tumblr.com/84f731e1b7c9ce8a81786f29b36762fc/
      tumblr_os45hx7DZw1vk5zz2o5_540.jpg');
-ms-transform: rotate(320deg);
      -webkit-transform: rotate(320deg); transform: rotate(320deg);
">
</div>

 
 

The spun stuff looks like this now:

 
 

Now comes the magic! We wrap our div in another div with the overflow: hidden; style to do the cropping. We must adjust the margins at our original div however to make the subset of what might be shown make sense. If we do not we are making a crop of the upper left corner of the turned image and we will catch the edge of where the image stops and dead space starts in our cropping. It's bad. Trust me.

<div style="width:81px; height: 195px; overflow:hidden;">
   <div style="width:540px; height: 400px; background-image:
         url('https://68.media.tumblr.com/84f731e1b7c9ce8a81786f29b36762fc/
         tumblr_os45hx7DZw1vk5zz2o5_540.jpg'); -ms-transform: rotate(320deg);
         -webkit-transform: rotate(320deg); transform: rotate(320deg);
margin-left: -113px;
         margin-top: -138px;
">
   </div>

</div>

 
 

This makes for:

 
 

If you want to get even more crazy and rotate the outer div, be my guest.

<div style="width:81px; height: 195px; overflow:hidden; -ms-transform: rotate(225deg);
      -webkit-transform: rotate(225deg); transform: rotate(225deg);
">
   <div style="width:540px; height: 400px; background-image:
         url('https://68.media.tumblr.com/84f731e1b7c9ce8a81786f29b36762fc/
         tumblr_os45hx7DZw1vk5zz2o5_540.jpg'); -ms-transform: rotate(320deg);
         -webkit-transform: rotate(320deg); transform: rotate(320deg); margin-left: -113px;
         margin-top: -138px;">
   </div>
</div>

 
 

We get:

Ugh, a rename of a branch in SourceTree can seem to create a second, duplicate branch at bitbucket.org.

Inside of SourceTree one may easily right-click on a branch and pick options for delete and rename to delete and rename, but the renaming has this shocking side effect. Is this a bug I've found? (using SourceTree 1.9.13.7)

 
 

Addendum 8/2/2017: This has not happened to me a second time.

Sunday, July 9, 2017

Fallout!

Alexis, a waitress who typically does graveyard shifts at a Pasadena, Texas IHOP has this pretty spiffy Fallout tattoo. I looked up Fallout at Wikipedia and apparently, it, as a game, has existed since the end of the 1990s, but I am only hearing of it now that I have moved to Houston (well, Deer Park) and I work with some millennial guys into games. I was able to recognize Alexis' tattoo for what it is after noting a colleague playing Fallout Shelter, a spinoff of Fallout that has sort of a The Sims-flavored, pimp-out-your-fallout-shelter-and-try-to-keep-it-afloat theme to it. The Android phone is a platform for the spinoff game. I have not played either game and I probably never will being an old man of Generation X but from the outside looking in I am fascinated by game themes the Wikipedia article on Fallout describes as retrofuturism. I have fallen halfway in love with vaporwave by which I mean that I like all (Mmm... well, many) of the vaporwave .gifs on tumblr and the aesthetic of pastels and palm trees out of the Al Pacino Scarface movie but I am less impressed with the music half of vaporwave which is clearly meant to be enjoyed on pot which I haven't touched in eleven years. I really have the same split opinion of Azealia Banks you know? She's a little firecracker and has me intrigued, but then you listen to her music and it's just like this watered-down elevator music of rap music that you should be on marijuana to get into. That band Pussy Riot sure has a good back story and it would be nice if there music was good too but it's not. I'm not really all that impressed with the girl acts of punk rock. Aimee Allen of The Interrupters might be the token girl in punk yours truly respects. Why are boys better than girls at punk rock? I digress. Anyhow, alongside vaporwave imagry I get a kick out of the retrofuturism of Fallout. I find myself Googling for images and the like. Retrofuturism is defined by Wikipedia as the now seemly goofy futuristic look of a bygone era, and I don't mean 1970s tacky metallic cloth clothing but instead, a farther back, pulp comic book Cybermen of Doctor Who thing. Picture people spacefaring in bubble glass helmets and otherwise skintight clothes. There is a Kennedyesque queso that is pervasive. It has and holds my attention. Let's strap on our rocket packs.

more of me trying to teach myself stuff

  1. Certainly it is possible to inject a service into a service at Angular 4. The service to be injected and the service to get the injection both go in the providers for the outermost module. Then at the service getting the injection two things happen. First the injected service is declared at the constructor as a variable as you might expect and secondly you will lead the declaration of the service getting the injection such as export class WhateverService with @Injectable() a needed form of "metadata" that may be looped in from @angular/core.
  2. this.whateverService.myUpdate.subscribe(
       (whatever: string) => alert("it's: " + whatever);
    );
    is an example of subscribing to an EventEmitter event at a service from a component. This is a good way to update state at one component from a parallel component that shares a service.
  3. Here is an example of using the TypeScript spread operator to add the individual elements inside of an array to another array, not the array itself!
    let yin = [1,2,3,4];
    let yang = [5,6,7,8];
    yin.push(...this.yang);
  4. Put a <router-outlet></router-outlet> tag inside of a component to have a nested component conditionally driven by routing! You need to wire up the routing in the outermost module wrapping everything. First loop in this import:
    import { Routes, RouterModule } from '@angular/router';
    Next, RouterModule needs to be added to the imports of the outermost module, but when doing so it should look like RouterModule.forRoot(myRoutes) and herein myRoutes is a variable that must be made elsewhere in the outermost module. It should be a const variable, probably placed above the @NgModule in the applicable file that looks something like this:
    const myRoutes = [
       {path: '', component: StartingOutComponent},
       {path: 'foo', component: FooComponent},
       {path: 'bar', component: BarComponent}
    ];
  5. a tags with href="/" and href="/foo" and href="/bar" will successfully trigger the routes above no different than going in the url line to http://www.example.com/ and http://www.example.com/foo and http://www.example.com/bar but the problem with this is that, just like changing the URL line, the whole of the app refreshes and not just the component in the <router-outlet></router-outlet> tag. To restrain the change to desired bit of the app you should instead use routerLink="/" and routerLink="/foo" and routerLink="/bar" and a link to http://www.example.com/bar could also take the shape of [routerLink]="'/bar'" and [routerLink]="['/bar']" and a link to http://www.example.com/bar/baz/qux could look like [routerLink]="['/bar','baz','qux']" with only the first piece of the route getting a leading slash.
  6. routerLinkActive="myClass" [routerLinkActiveOptions]="{exact:true}" in an a tag with a routerLink setting will apply myClass as a CSS class to the a tag if the route in routerLink is active, matching the route exactly. This gimmick is smarter than you might think. You could have it inline not at the a tag but at a list item wrapping the a tag and it will still somehow work. The routerLinkActiveOptions bit enforces exact matches so that a single slash by itself for the "home page" will not get matched when someone goes to /foo however if you always want /bar to be matched regardless of whether or not one is at /bar or at /bar/baz/qux maybe you should leave this setting off.
  7. How may we navigate to a component/route programmatically in TypeScript? Alright, at a component you will want to loop in this import:
    import { Router } from '@angular/router';
    Then loop the Router in as a variable at the constructor like so:
    constructor(private myRouter: Router){
    And, finally, use the variable like this to have an absolute path to http://www.example.com/bar/baz/qux
    this.myRouter.navigate(['/bar','baz','qux']);
  8. Alright, let's say that we are TypeScript side at the bar component for http://www.example.com/bar and we want a link that will navigate to http://www.example.com/bar/baz/qux moreover. Well, the three lines of code immediately above could be refactored to accommodate this while using a relative path.
    import { Router, ActivatedRoute } from '@angular/router';
    Then loop the Router in as a variable at the constructor like so:
    constructor(private myRouter: Router, private myActivatedRoute: ActivatedRoute){
    And, finally, use the variable like this to have an absolute path to http://www.example.com/bar/baz/qux
    this.myRouter.navigate(['baz','qux'], {relativeTo: this.myActivatedRoute});
    Outside of TypeScript, at routerLink links in HTML templates, leaving off the leading slash or having ../ is the way to get relative links to work. Do note that there is a distinction between a relative path from outside the components that change out at <router-outlet></router-outlet> and the outer component wrapping everything where the relative paths always behave as if coming off the root path. At components actually used in routes, relative paths at routerLink links are relative to the current route at hand so ../ off of http://www.example.com/bar is going to take one to http://www.example.com/
  9. const myRoutes = [
       {path: '', component: StartingOutComponent},
       {path: 'foo', component: FooComponent},
       {path: 'foo/:id', component: SingleFooComponent},
       {path: 'bar', component: BarComponent}
    ];
    shows off the ability to pass a variable at a route. Note that we will use a different component for /foo/whatever than for /foo.

We need to fix your Microsoft account before you can use shared experiences. Select this message to open Settings and fix things.

To get around this error to do with my Microsoft Account (MSA) at Windows 10 I ran https://download.microsoft.com/download/F/2/4/F24D0C03-4181-4E5B-A23B-5C3A6B5974E3/microsoftaccounts.diagcab and happy pass stepped through a wizard. The process stopped for me partway through and I got an error about an inability to sync with some service, but nonetheless the problem went away too.

Saturday, July 8, 2017

Beware of pushing service calls for data calls too far down an arrangement of nested Angular 2 components.

A coworker suggested to me that a mistake made by another developer where I am who didn't last was to make an Angular 2 component for picking an address that called out directly to a service to get a list of job sites which entails hitting an API endpoint to have C# query a database. The problem with this came in when two component instances sat side by side in the application. Example: In some inventory management scenario across company divisions where you have a form where you select a billing address and a shipping address for product to be moved and those two things (component instances) sit next to each other at a little form we have a problem. Two calls are made to the database for the same list of records. Boo! Instead the call should be made from a service call outside the components and the accrued data should be handed in. Don't repeat yourself. This is a really easy mistake to make and I could easily imagine myself making this mistake when a coworker told me about it. It just seems at first that the call to get the job sites goes with the component to manage a street address selection, right?

Friday, July 7, 2017

How do I phone call someone over Slack?

Go into a chat history you have with that person and click on their name above one of the things they have said to you. You will see a modal with an option for "Call" to click on. If you've never had a chat with the party in question, click on the plus symbol at the right of DIRECT MESSAGES and then find the individual to start a chat up. You'll see their name and avatar in new chat history which just starts off saying "This is the very beginning of your direct message history with Yuri Namehere." and you should click on the avatar as it will bring up a summary for the person at the right which will have a "Call" button. Click the "Call" button.

What do I do if I accidentally close the "Project" pane in WebStorm?

The "Project" pane is that thing that's kinda like "Solution Explorer" in Visual Studio. It shows a file tree/folder structure breakdown and it sits at the left edge of WebStorm. If you close it, you may just open it again by clicking on the leftmost of the breadcrumbs out to a file you have open. This will be at the upper left.

Wednesday, July 5, 2017

Yes, you should probably shred documents, but you're not going to shred your notes right?

Well, what if your notes have a password in them? Should they just sit on your desk? Therein is a dilemma, huh? ...especially so for PCI compliance. I guess you could encrypt your notes by writing passwords backwards, cub scout style, but how could you ever argue that there is obfuscation under an audit? Ha! Glenn Burnside once asked me about one of the books I scribble in at work. There have been a few. I think I got the idea from Rod Paddock, intrigued by the book he kept. In a three monitor setup my book to note take in seems to be my fourth monitor. I feel really awful when it's not there should I forget my journal at home. It helps me think/focus.

Tuesday, July 4, 2017

There is sort of a Venn diagram thing going on in mapping JSON objects into [FormBody] led variables at Microsoft.AspNetCore.Mvc controller actions.

The properties in common get kept. The properties at the C# POCO with no dance partners just end up null or sporting a default value. The properties at the JSON object with no dance partners are harmlessly lost/dropped.

Monday, July 3, 2017

Assigning to a variable a where clause in C# is, yes, a use case for a Func!

Assuming...

return myIQueryableSoFar.Where(MyStaticClass.MyStaticFunc);

 
 

We could call out to a static method in our static class named MyStaticClass which would look like this:

public static Expression<Func<MyQueriedType, bool>> MyStaticFunc
{
   get
   {
      return (x) => x.meatyCondition != null;
   }
}

LINQ to Entities does not recognize the method 'System.Guid get_Item(Int32)' method, and this method cannot be translated into a store expression.

This error is telling you not to fish something out of a list or array midstream in the LINQ mechanics. Pull that item out to a variable upstream first.

JavaScript-side sanity check for viability of what would be nullable Guids in C# cannot (should not) just be a falsey check.

I recommend instead:

if (foo.barId && foo.barId != '00000000-0000-0000-0000-000000000000'){

 
 

This may be overkill if you are really confident you are not assigning = new Guid(); anywhere, but I would not be too sure of your ruleset (your developers' discipline). You ever tell everyone to use the external dependency for timekeeping instead of sprinkling DateTime.Now everywhere and no one seems to get it?

Custom validations at Angular 4 forms.

Look! It's a thing! I'm not yet sure if there is a way to do something foolproofesque and compare two dates. This might have a way... or this

Make a mailto href link!

W3 schools has this example of making a link that when clicked opens up your email client and preps it to send an email to someone@example.com with "Hello again" as the subject. Beautiful. It is funny I didn't yet have an example of this at this blog. I guess I haven't made a vanity web site for someone since I started this blog in 2011.

<a href="mailto:someone@example.com?Subject=Hello%20again" target="_top">Send
      Mail</a>

Sunday, July 2, 2017

Angular 4 Forms 101

Do note:

  1. You need to loop in the FormsModule at your module.
  2. You need to wrap form elements in form tags and the opening tag should be something like so:
    <form (ngSubmit)="whatever(x)" #x="ngForm">
  3. This allows for something like this:
    whatever(me: NgForm) {
       let foo = me.bar;
       let baz = me.qux;
  4. Above bar and qux are input fields inside the form tag and this trick slurps out their values. In order to get this to work the name attribute needs to go back into the form tag and it needs to be accompanied by ngModel too. Basically name="bar" ngModel and name="qux" ngModel need to go inside the form field tags.
  5. A submit type button like so may submit the form:
    <button type="submit" [disabled]="!x.valid">Go</button> ...and you'll notice the pseudovalidation. I'll get to the real validation stuff soon.
  6. To make the quasivalidation work at the bar and qux controls just add required inside their tags. If you need a more specific validation you can also put this inline in the tag to loop in regular expressions [pattern]="'^whatever$'"
  7. You may use the ViewChild trick to get #x into the TypeScript side of the component. Let's say it becomes a variable called w there. Well then, you may do something like this to set the values of bar and qux:
    this.w.setValue({
       bar: "cat",
       qux: "dog"
    });
  8. this.w.setValue.reset(); will reset our form.
  9. import { FormGroup } from '@angular/forms'; lets you bring in FormGroup for reactive forms. Make one inside the template class but outside any methods with v: FormGroup; and then make an assignment elsewhere like this:
    private stageForm() {
       this.v = new FormGroup({
          'myControl': new FormControl('default value here'),
          'somethingElse': new FormControl('make sense now?')
       });
    });

    Call stageForm(); above from ngOnInit. :)
  10. import { FormsModule, ReactiveFormsModule } from '@angular/forms'; needs to be looped in at your module for reactive forms.
  11. <form [fromGroup]="v"> is what the form tag will look like. The stuff you have between the open and close form tag, the HTML for form guts, kinda gets used as a template within your template. You may assign the controls you defined on the TypeScript side to controls therein. Put formControlName="myControl" and formControlName="somethingElse" inside of existing input tags (or textarea or select tags... whatever) to make this happen.
  12. Loop in FormArray of angular/forms to have some multirow content in your form. You may "new up" (instantiate) one like so:
    let gadgets = new FormArray([]);
    gadgets.push(
       new FormGroup({
          'torque': new FormControl('13'),
          'gauge': new FormControl('42')
       });
    );

    Then inside of a form, let's use our v form, you may loop through the array at the template like so:
    <div *ngFor="let gadget of v.get('stuff').controls; let i=index"
          [formGroupName]="i">

    What is stuff you ask? Well, that is a good question. You will need to revamp the setup of v like so:
    private stageForm() {
       this.v = new FormGroup({
          'myControl': new FormControl('default value here'),
          'somethingElse': new FormControl('make sense now?'),
          'stuff': gadgets
       });
    });

    Alright, at the loop template inside of the form template inside of the component template (it's all the same file) you will need to use the formControlName trick to assign torque and gauge to controls.
  13. (<FormArray>this.v.get('stuff')).push(
       new FormGroup({
          'torque': new FormControl(),
          'gauge': new FormControl()
       });
    );
    would be an example of adding a new row to the form rows after the fact. This one has no values, it would be of a fill-in-a-new-record flavor.
  14. Loop in Validators of angular/forms to do... validations! You'll set them up like so, and yes this is something different than disabling the submit button:
    private stageForm() {
       this.v = new FormGroup({
          'myControl': new FormControl('default value here', Validators.required),
          'somethingElse': new FormControl(null [
             Validators.required,
             Validators.pattern(/^
    whatever$/)
          ])
       });
    });
    and how this will take shape was a bit of a surprise to me. You will notice that we are not including an error message in the validation code so what is it going to tell us when things go South? Well this process is not going to cough up some copy in a new div sitting side by side with a control as you might expect in a web forms or an ASP.NET MVC approach. Instead it just gives the ng-invalid style to that which is invalid. You will not want to style .ng-invalid{ in your stylesheet however as this is too general and will style the whole of any form that has even one validation error. Instead try something like .input.ng-invalid.ng-touched{ wherein the first bit restrains your style at your stylesheet for the component to input tags and the end bit makes it so that if a control starts out empty it is not angry until you click in it and then continue to give nothing or the wrong sort of something.
  15. let slurpOut = this.v['myControl']; is an example pulling something back out of a form. The multirow thing can just fit to an array of a particular type.
  16. (<FormArray>this.v.get('stuff')).removeAt(myIndex); should be gold for dropping a row out of the rows. myIndex here would correspond to i handed into a TypeScript method from the template.

 
 

In learning this stuff I also learned:

  1. let y = new Subject<Whatever[]>(); is an example of an RxJS helper that one may loop in with:
    import { Subject } from 'rxjs/Subject';
  2. import { Subscription } from 'rxjs/Subscription'; will similarly loop in subscriptions. Make one inside the template class but outside any methods with z: Subscription; and then turn around and do a subscribe with something along the lines of maybe this.z = this.that.theotherthing.subscribe(); and do an unsubscribe to prevent a memory leak with this.z.unsubscribe();
  3. Router may be looped in from @angular/router and I don't really understand the routing yet. One may navigate up a folder like so:
    this.myRouter.navigate(['../'], { relativeTo: this.myRoute });

 
 

Addendum 12/19/2017: In bullet point eleven fromGroup should really be formGroup. Duh.

 
 

Addendum 3/28/2020: There should probably be a comma after the null in the code in bullet 14.

midway

Did you know that July 2nd is the day in the middle of the year? There are 182 days on either side of it... well, unless it is a leap year... then there is no day in the middle of the year and the midway point is the midnight when July 1st becomes July 2nd. Anyhow, it's not a leap year this year so today is the day in the middle of the year.