- Taobao is some sort of marketplace like eBay or Amazon I guess. It's Chinese. So is WeChat which is some sort of Chinese Facebook Messenger/Facebook thing.
- I hate how the word bimonthly can either mean twice a month or every two months in the English language.
- tbh means "to be honest"
- Visual J++ is Microsoft's version of Java which no longer exists and Delphi is some offshoot of Pascal.
- www stands for World Wide Web
- .epub is an e-book file format.
- MFC (Microsoft Foundation Class Library) is a C++ library for desktop apps.
- INETA is the International .NET Association. (i.e. just another .NET User Group)
- MoviePass, bundled with iHeartRadio which allows one to listen to some radio stations online, has a price tag that has fallen under $37 per month. Go get it while it's cheap. If you see four movies in the next three months you are in the black.
- 123movies.com is another movie piracy site. Some of the kids I work with who use this stuff are telling me that the playback from these movie piracy sites has gotten choked down really slow. Is it a DDoS attack from Hollywood or just what happens when you don't have Net Neutrality?
- Solidity is another programming language and I think there is some Ethereum stuff that uses it though I don't really know what I'm talking about.
- Those maps on your iPhone haven't been Google Maps in a long time. The iPhone maps are now Apple Maps. You may independently download a Google Maps app for the iPhone from the App Store.
- Apple Lisa was an old desktop computer.
- Dr. Seuss (Theodor Seuss Geisel) came up with the term Nerd as best as I can tell. It's a goofy being in one of his books.
- Internet Explorer for Mac ...it was a thing for a little while.
- Wire JS is a JavaScript IoC (Inversion of Control) container. I kinda thought HorseJS was something for that too, but the more I look at it the less it makes sense.
Monday, April 30, 2018
April Queso
app.UseStaticFiles();
"ASP.NET Core 2 and Angular 5" by Valerio De Sanctis points out in Chapter 1 that if you comment out this line of Startup.cs in an ASP.NET Core web app that the application will be unable to serve up CSS or JS files and also static HTML files too.
Sunday, April 29, 2018
Rolla, Missouri
I drove through Rolla today on an uneventful road trip to the Lake of the Ozarks State Park (It's not all that.) and it made me think of 4 Guys From Rolla.com which as a blog which tells you how to do stuff like save emails sent from C# off to a directory as .eml files as suggested here. Hmmmm. Seems to be a link to a different blog, eh? (It looks like on a SmtpClient you can set a PickupDirectoryLocation to do the file saving.) I don't think there is any new 4 guys content. Maybe the site now just links off to other stuff in its dying state. Anyways, as this explains, Scott Mitchell was one of the four guys when he was at the University of Missouri at Rolla and he coaxed three others into forming The Beatles with him and two of the four didn't stick around for long at all, just long enough for the name to stick, and... anyhow the rest is history. I always assumed Rolla was somewhere in California but it turns out it is in Missouri. It's not very interesting. The photo here is from randomly inside of a Stake 'n Shake there where I bought a chocolate shake.
Test upload and download speed.
I found http://openspeedtest.com/ just now and it seems legit. Hopefully I am not steering you towards something sinister.
Saturday, April 28, 2018
Methods with a fat arrow after the signature instead of curly braces and return statement...
In both C# and TypeScript will be one line long and will return what is immediately after the fat arrow. The return keyword is implicit. Just pretend it leads everything else after the fat arrow. In TypeScript it can be any function and not just the functions that are methods (functions hanging off of JSON objects as properties are "methods" in JavaScript) and what is more, you may wrap what is immediately after the fat arrow in curly braces if you want to explictly use the return keyword which would go where it implictly was implied before. (You'll figure it out.)
How does the default Program.cs vary between version 1 and version 2 of .NET Core?
Pages 32 and 33 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis touch on this some and basically what is at bullet four here becomes:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
namespace TestMakerFreeWebApp
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
A host is an execution context for a .NET Core app and if we are doing something for the web we must implement an IWebHost interface as shown above with WebHost.CreateDefaultBuilder which now stands in place of all of the customization logic that explicitly said "Let's use Kestrel." and the like. The only customization is .UseStartup<Startup>() which suggests "Let's find Startup.cs as the second file to use next." and nothing more. I don't yet know how to explicitly NOT use Kestrel, but then again when is that going to come up? WebHost.CreateDefaultBuilder also finds the content root folder holding appsettings.json which is the new web.config.
Command, Repository and Mediator design patterns.
This has a little write up on the three. We all know what the repository pattern is, right? A repository is the infrastructure project level machinery for getting an object of a particular type to and from the database in Onion Architecture. Command feels like the actions in the Redux stuff and Mediator is harder to understand. Rules wrapping objects defining how they are used? The copy in the first link I provide suggests it is like the Facade pattern which seems to be about having a front door like an interface or a wrapper "protecting" the guts of some machinery. It also suggests it may be used with the Observer pattern. Facade+Observer=Mediator? The Pragmatic Programmer by Andy Hunt and Dave Thomas is perhaps a book that goes into patterns some. This is all on mind after an exchange over lostechies.slack.com in which I roll my eyes at the patterns and offer:
- I'm missing something with the patterns. Those old patterns like the decorator pattern which so violates DDD just seems like something I would never use. It is so niche. Most of them are, so particular they are impractical. Think of the first chapter in Head First Design Patterns which dips into the strategy pattern and has duck inheriting from rubber duck in a Liskov violation. I read that chapter and I stopped reading the book after that. I never see a pattern anywhere I work beyond the overall architecture. I never think "Oh, today I'm going to use the Observer pattern to solve this problem."
- ugh, other way around ... the book had rubber duck inheriting from duck
- I guess I see patterns in frameworks and perhaps in the architecture of a particular application but in both of those cases it isn't really put upon the average Joe developer to think of what pattern to use to solve a problem or see the way to cut through the hedge maze by picking the right chainsaw. Instead, downstream of big upfront decisions, there is little elegance or ingenuity. At that point everyone is just wandering inside of the hedge maze instead of trying to make it better.
It may have been a decoy duck instead of a rubber duck honestly...
Friday, April 27, 2018
VIDEO versus SLO-MO versus TIME-LAPSE
SLO-MO and TIME-LAPSE are newish options for video on the iPhone beyond the regular VIDEO. SLO-MO is slowed down and TIME-LAPSE is sped up.
In a .NET Core application the "Resources" folder of a .NET Framework application is replaced by the "Dependencies" virtual folder.
I already knew this, but I have not yet blogged of it and I read about it today in "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis.
Thursday, April 26, 2018
You may move some inline properties for SVG tags out to CSS, but not all of them.
<!DOCTYPE html>
<html>
<head>
<title>Whatever</title>
</head>
<style>
section {
color: #FFFFFF;
text-align: center;
display: table-cell;
position: absolute;
font-family: Arial, Helvetica, sans-serif;
font-size: 10px;
line-height: 10px;
}
</style>
<body>
<svg height="200" width="360">
<circle cx="260" cy="100" r="94" fill="red" />
<circle cx="100" cy="100" r="94" stroke="white" stroke-width="3" fill="blue"
fill-opacity="0.6" />
<circle cx="260" cy="100" r="94" stroke="white" stroke-width="3" fill="none" />
</svg>
<section style="margin-top: -108px; margin-left: 50px;
width: 100px;">liberal</section>
<section style="margin-top: -128px; margin-left: 175px;
width: 10px;">s w i n g</section>
<section style="margin-top: -108px; margin-left: 210px;
width: 100px;">conservative</section>
</body>
</html>
What is above may be refactored like so:
<!DOCTYPE html>
<html>
<head>
<title>Whatever</title>
</head>
<style>
.conservative {
fill: red;
}
.conservativeOutline {
stroke: white;
stroke-width: 3;
fill: none;
}
.liberal {
fill: blue;
stroke: white;
stroke-width: 3;
fill-opacity: 0.6;
}
section {
color: #FFFFFF;
text-align: center;
display: table-cell;
position: absolute;
font-family: Arial, Helvetica, sans-serif;
font-size: 10px;
line-height: 10px;
}
</style>
<body>
<svg height="200" width="360">
<circle class="conservative" cx="260" cy="100" r="94" />
<circle class="liberal" cx="100" cy="100" r="94" />
<circle class="conservativeOutline" cx="260" cy="100" r="94" />
</svg>
<section style="margin-top: -108px; margin-left: 50px;
width: 100px;">liberal</section>
<section style="margin-top: -128px; margin-left: 175px;
width: 10px;">s w i n g</section>
<section style="margin-top: -108px; margin-left: 210px;
width: 100px;">conservative</section>
</body>
</html>
Both files do the same thing!
There's really not a way in HTML to increase the width between the underline of a link and the copy on the link.
You could make the link have no underline and then sit it inside a div with a bottom border on it to fake the effect.
How do I nest some of the controls inside of an Angular 4 reactive form in their own components?
Let's say our nested component looks like so:
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'joy',
templateUrl: './joy.component.html'
})
export class JoyComponent {
@Input() MyGroup: FormGroup;
}
Let's give it an amazingly simple template.
<ng-container [formGroup]="MyGroup">
<input formControlName='yang' />
</ng-container>
Fine. Now how may we drag it into some sort of bigger picture?
import { Component } from '@angular/core';
import { NgForm, FormGroup, FormArray, FormControl } from '@angular/forms';
@Component({
selector: 'front-door',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.css']
})
export class LayoutComponent {
whateverForm:FormGroup;
ngOnInit() {
let first = new FormGroup({
'yin': new FormControl("13"),
'yang': new FormControl("23")
});
let second = new FormGroup({
'yin': new FormControl("27"),
'yang': new FormControl("42")
});
let third = new FormGroup({
'yin': new FormControl("69"),
'yang': new FormControl("86")
});
this.whateverForm = new FormGroup({
'lineItems': new FormArray([first, second, third])
});
}
constructor() { }
whatever(x: NgForm) {
console.log(x);
}
}
The component above and its template below show off crosstalk with the JoyComponent. If you change a value at the form field inside the JoyComponent and press the button the dirty flag for the whole of the form will get logged as true because a form field was affirmed as changed.
<form [formGroup]="whateverForm" (ngSubmit)="whatever(x)" #x="ngForm">
<table formArrayName="lineItems">
<tr *ngFor="let lineItem of whateverForm.get('lineItems').controls; let i=index"
[formGroupName]="i">
<td>
<input type="text" formControlName="yin" />
</td>
<td>
<joy [MyGroup]="lineItem"></joy>
</td>
</tr>
</table>
<input type="submit" />
</form>
It's not that tricky.
One may use .markForCheck() instead of .detectChanges() off of a ChangeDetectorRef in an Angular 4 application.
If you change a property on an Input but not the whole object in the manner that would normally tigger change detection in a OnPush ChangeDetectionStrategy circumstance, that will not kick off a refreshing. You may do so with .markForCheck() as explained here. I guess it has a narrower scope than .detectChanges() which I think is going to find anything that changed.
CHANGELOG.md
By searching for 18902 (not f078ab8) at the CHANGELOG.md one may see that the change is part of Angular 4.4.1. This can be an OK resource for determining what changed when in Angular.
I attended the St. Louis Angular Lunch for the first time yesterday.
It's hosted out at the West edge of St. Louis at Oasis Digital. A lot the people there were with Oasis Digital which does Angular trainings and certainly all four of the panelists shown here, from left to right Christina Hardin, Cory Rylan, Paul Spears, and Lance Finney, work at and train for Oasis Digital. These four had recently attended ng-conf which is an annually reoccurring Angular conference and they spoke of their thoughts. A majority of persons in the room had attended the conference too and so others piped up as well. The conversation wandered a little beyond that too detailing that ngxs is a new rival to NgRx (annotations instead of pure functions) for example, but predominately allowed me once again vicariously experience a conference as I had here and here. I enjoyed the St. Louis Angular Lunch.
StackBlitz, an online IDE kinda like Plunker but better, was the star of ng-conf. Eric Simons and Albert Pai are the inventors. StackBlitz allows you to draw in dependencies a lot quicker than the typical doctor-ups of package.json followed by npm install approach as the dependencies are all there online in its own machinery already. You may publish out a package.json when you are ready. When you run an application you will have a URL that you may just share out to let others play with the instance of the app. Supposedly, at the conference a speaker was doing some live coding of a PDA (personal digital assistant) and invited the audience to pull up the app on their phones. What is more eventually there was some sort of raffle across all of the connections connected to the app and a winner got an alert at his phone and put his hand up in the crowd to claim some sort of prize. Schematics was mentioned as a code generation tool. Apparently, it will make all of the NgRx store machinery too for a collection such as a reducer file. A rival to this approach lies in ngrx-data which John Papa and Ward Bell presented on. It is built on top of "NgRx entities" which offer some capabilities to work with collections coming from Observables a little better. Taking it a step farther with ngrx-data you may sort collections and find the item at position X and a lot of the LINQ and Lambda stuff of C# basically. How does that rival Schematics? I guess the acrobatics you might undertake in some of the generated files for, I dunno, sorting perhaps might just be undertaken inline in manhandling an Observable. Angular Elements allow for the packaging up of reusable elements and even Angular itself is now down below 1K in size so it may just be packaged up as a part of an element and that element may be used in other web sites that are not even Angular sites. The ability to destroy a component has been removed from the Angular CLI. ng-packagr is a third party tool for drawing in libraries and now the Angular CLI works well with third party tools and allows you to make calls to them so there was a lot discussed on pulling in third party libraries with the Angular CLI. ng add and ng update are newish things in the CLI. Sam Julien of Portland, Oregon has a series of videos online on how to migrate from AngularJS to Angular.
How do I find the index of an enum in TypeScript when all of the options have string settings?
What if we changed up the Nordic enum as shown here like so?
enum Nordic {
Denmark = 'Denmark',
Finland = 'Finland',
Iceland = 'Iceland',
Norway = 'Norway',
Sweden = 'Sweden'
}
What would sabotage the code then, wouldn't it?
let noTrees: number = Nordic['Iceland'];
alert(noTrees);
I don't see a way around this in order to get a numeric index short of looping through the enum values as suggested here while incrementing a counter and having some conditionally logic to assign the counter off to another variable at the right time.
Turn off the HTML formatting that happens whenever you save a file in Visual Studio Code 1.17.2.
Add the following at: File > Preferences > Settings
"html.format.enable": false
I used relativeTo in Angular routing yesterday for the first time.
I was able to refactor this...
this.router.navigate(['/foo/bar/baz/', qux]);
...into this:
this.router.navigate(['../', qux], {
relativeTo: this.activatedRoute
});
My constructor of my component looks like this:
constructor(private activatedRoute: ActivatedRoute, private router: Router) {
I have this import up top.
import { ActivatedRoute, Params } from '@angular/router';
Find everywhere a variable is used in a file in Visual Studio Code 1.17.2.
Right-click on the variable and pick: Find All References
How do I loop through ViewChildren in an Angular 4 application and affect them?
Let's say we have a bunch of tabs which are a third party component which we nest in our own component like so...
<my-tab *ngFor="let segmentTier of segmentTiers" #tabs>
</my-tab>
...and loop in at the TypeScript side like so:
@ViewChildren('tabs') tablist: QueryList<MyTabComponent>
Well, let's also say that we want to set which tab is selected based on a route parameter that is called "segment" for example. We can do that in the ngAfterViewInit lifecycle event like so:
ngAfterViewInit(): void {
this.activatedRoute.params.subscribe(p => {
const segment = p["segment"];
let tabPosition = 0;
let index = 0;
for (let letter in SegmentationType) {
if (letter === segment) tabPosition = index;
index++;
}
if (this.tablist) {
this.tablist.changes.subscribe(tl => {
tl._results.forEach((t, index) => {
const tab = <MyTabComponent>t;
if (index === tabPosition) {
tab.active = true;
} else {
tab.active = false;
}
});
this.ref.detectChanges();
});
}
});
}
Do note that there is no way to manually destroy the changes.subscribe. It will automatically clean itself up under the hood like the params.subscribe does for routing. There used to be a bug in which that didn't happen, but as of Angular 4.4.1 that has been fixed. Here are some links on as much:
Wednesday, April 25, 2018
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
This is more magic from Chapter 1 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis. This command line command updated the canned UI templates for Visual Studio 2017. In looking at what gets spit out to the console it looks like there are templates for Vue and Knockout and Aurelia and Angular and React!
Can't bind to 'formGroup' since it isn't a known property of 'form'.
Fix that by adding ReactiveFormsModule at your own module at imports. Import it like so:
import { ReactiveFormsModule } from '@angular/forms';
[formGroup] at a form tag in an Angular 4 app
The form I elude to here would have a front end template that starts out like so:
<form [formGroup]="presidentsForm">
<div class="headerWrapper">
<div class="headerRight">
Nonconsecutiveness?
</div>
<div class="headerMiddle">
Party
</div>
<div class="headerLeft">
Name
</div>
</div>
<ng-container formArrayName="lineItems">
<div *ngFor="let lineItem of presidentsForm.get('lineItems').controls; let i=index"
[formGroupName]="i" class="lineItem">
Inside of the *ngFor we would have controls like so:
<input type="text" formControlName="name" />
Have an optional parameter at the end of a route in Angular 4.
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { MyComponent } from './whatever.component';
import { MyService } from './my-resolver.service';
export const MyRoutes: Routes = [
{
path: '',
component: WhateverComponent,
resolve: {
'MyResolver': MyResolverService
}
},
{
path: ':id',
component: WhateverComponent,
resolve: {
'MyResolver': MyResolverService
}
}
];
@NgModule({
imports: [
RouterModule.forChild(RelationshipsRoutes)
],
exports: [RouterModule]
})
export class MyRoutesModule { }
Tuesday, April 24, 2018
dotnet new angular
...as a command line command seems to set up one of the canned Visual Studio 2017 and .NET Core Angular projects. The downside of that is that it only sets up a .csproj file and not a .sln and bigger solution. You may be ahead to just set up a new Angular project through the GUI that comes from going to: File > New ... The canned project is intriguing. There is a ClientApp folder at the root of the project which has all of the Angular code and somehow gets looped in. I guess one of the controllers serves it up. Outside of the ClientApp folder however there are just the usual folders like "Controllers" and "Views" that you might expect. There is a wwwroot folder which will end up with a dist folder inside of it too where your TypeScript stuff compiles out to upon a build. The heartache of setting that up has already been care of for you. You don't have to think about task runners like Grunt and Gulp for as much. Chapter 1 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis had me goofing off with this stuff this morning. Server-Side Rendering (SSR) for SEO is also baked in.
Monday, April 23, 2018
What happens when you forget the spread operator in TypeScript?
This...
let yin = {
foo: 13,
bar: 42,
baz: 69,
qux: 86
}
let yang = {
yin
}
console.log(yang);
...gives us this:
{
yin: {
foo: 13,
bar: 42,
baz: 69,
qux: 86
}
}
While this...
let yin = {
foo: 13,
bar: 42,
baz: 69,
qux: 86
}
let yang = {
...yin
}
console.log(yang);
...gives us this instead:
{
foo: 13,
bar: 42,
baz: 69,
qux: 86
}
Find the items that two arrays have in common in TypeScript using .filter!
let yin = [13, 42, 69];
let yang = [42, 69, 86];
let venn = yin.filter(y => {
if (yang.indexOf(y) > -1) return true;
});
console.log(venn);
Sunday, April 22, 2018
I saw Kevin Grossnicklaus speak on Azure yesterday.
Kevin was the opening act for this event. Everything in Azure at its highest level is a "resource." A resource can mean many things. DTUs (database transaction units) are a measurement of how many concurrent calls you need per X number of users, etc. Underneath Azure there is a very rich API and it is possible to talk to Azure through PowerShell scripts. There are datacenters for Azure all over the world. It possible to have your stuff randomly assigned to a CSP (cloud service provider) and it also is possible to specify a datacenter. US DoD East is for example a data center for the American government to secure its doings and isolate its data from other data.
The European Union has stricter data-keeping standards than America and there will be the need for European interests to be hosted on EU compliant servers such as "North Europe" in Ireland. The Brexit is challenging British use of the "North Europe" server apparently. Kevin touched on IaaS versus PaaS versus SaaS though his description of PaaS was different from my original understanding as suggested here. Infrastructure as a Service entails spinning up VMs. You may pick your operating system, be it Red Hat or be it Windows. Software as a Service can mean IIS in the cloud or it can mean subscribing to someone else's Azure hosting software for a fee. That's not really new. Platform as a Service was however described today as maybe something like a SQL database in the cloud that you could limitedly talk into through a connection string, more limited in scope than spinning up SQL Server yourself on a IaaS VM but also a little more to the point as well. Paying for a subscription to use Visual Studio or the PowerBuilder IDE for SAP stuff are other examples. Key Vault, a service for saving private keys in your apps, is yet another PaaS trapping still. Setting up your own infrastructure outside of Azure entails a lot of chores that go away with IaaS and from there even more chores go away with PaaS and finally SaaS takes the most off your plate as seen here:
Beyond the portal at https://portal.azure.com there is a shell at https://shell.azure.com and you may run command line commands there such as az vm list to see a list of your VMs. Logic Apps make for the modern BizTalk implementations, inter-organization middleware (bridges between OS and software or software and a database or whatever) allowing for process automation. Cerebrata has UI tools for Azure. Storage Explorer is sort of the FileZilla for file storage at Azure. There is a distinction between Premium and Standard Storage which has to do with whether or not you are using RAID (Redundant Array of Independent Disks and originally Redundant Array of Inexpensive Disks) Arrays which spread work across multiple disks. Crazy things you may use in Azure like the Face API for recognizing an identity based upon a photo allow you to up your game in terms of what you can realistically do when you build an app. The so-cost-prohibitive-it's-impossible is getting easier as you don't have to roll it yourself.
Kevin mentioned that a lot of the kids he works with have never seen a five and a quarter inch floppy disk and don't know what they are beyond a save icon. I wasn't used to seeing all of the fountains at the event. You never see these anymore in Texas because they are so wasteful. I'm not in Texas anymore though.
What are TypeScript Typings?
This was per this a tool to install typings which made jQuery or moment.js play nicely with TypeScript. Basically, the challenge was that while JavaScript is "untyped" there are types in TypeScript and if you want to use jQuery or moment.js or some other untyped JavaScript library amongst the types it can cause chaos. There are type declaration files with .d.ts extensions that give types to the untyped faking it like it fits, get it? This came up on page 23 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis which gives the reader an enormous guilt trip for maybe being eventually mad at the fact that the code at the Packt site will eventually be out of date as things change over time and the book ages five or ten years. I digress. The Stack Overflow article I reference here also suggests that npm now takes care of this problem and not the thing in the first link I provide, not any longer anyways.
Saturday, April 21, 2018
I saw a talk on App Services for developers today.
The speaker was an R. Michael Querimit of Microsoft and the event was the 2018 Global Azure Bootcamp, a Microsoft sponsored community event designed to promote Azure. Michael Querimit asked the room "Who here is a developer?" or something like that and a lot of us put our hands up. He built on top of that by suggesting that if we do all of the things that distract us from development, such as prepping a machine to host the code, the Azure way, at the cloud, that an immense amount of time will be saved allowing us to really focus on the real work and be more productive. He went out to the Azure Portal and showed us a lot of tricks and, yes, it all seemed pretty easy. There is a distinction between Web Apps, API Apps, Mobile Apps, and Logic Apps with the last of these being workflows and the first three being very similar variants of IIS hosted applications in the cloud with only the included-by-default .dlls changing up across the three. Michael focused on Web Apps and made one and went on to show off how if a processor rose above 80 percent (or whatever percentage you'd like) usage that a new instance of the app could be set up to offset the heavy traffic. You can write your own rules (all in the labyrinth-deep cockpit of controls that is the Azure Portal) that kick in for as much while allowing yourself to otherwise have as few instances as possible to save costs. There is a brief cool down period when a spike or a drop happens before a rules-based addition or reduction kicks in to make sure the phenomenon is the new normal and not just a fluke. In Michael's words, this, and similar features, allow the little guy to be just as flexible and robust in the DevOps sphere as major enterprises. All of the settings you might put in a Web.config file can just get stored in the various settings in Azure Portal if you'd like. You can push an app to a staging deployment before really rolling it live to troubleshoot and test. There may be times that you will need to talk to on-premise data, for example if your organization is just afraid to have its sensitive data out in the wild, and that is all doable too. Telemetry data (data gathered from endpoint interactions) gets sent to Application Insights and Application Insights can tell you all sort of metrics on what is going on with your stuff. There are helpers for HIPAA and PCI compliance.
This event was at St. Louis Community College in Bridgeton, Missouri which is a St. Louis border town. Microsoft held similar events today in other U.S. Cities and I believe also beyond the states in the world at large. I guess that would make the "Global" part of 2018 Global Azure Bootcamp make sense.
There are a lot of ugly brown buildings in St. Louis. Many of them were once-upon-a-time, one hundred years ago, beautiful red brick buildings which have turned brown over time, but today's building was just built with an ugly brown exterior to begin with. Inside however, you would not believe how over-the-top posh things were. Just look at that fountain! This is kinda a good analogy for Azure itself. I've never warmed to it because it seems ugly from the outside looking in. I am surprised by how beautiful it gets upon closer inspection.
Friday, April 20, 2018
holding Ctrl and using the scrollwheel and/or holding Ctrl and using the plus and minus keys at Google Chrome's browser
This will zoom the browser in and out.
Loop through all of the values in an enum in TypeScript.
enum LetterGrade {
A = 'A',
B = 'B',
C = 'C',
D = 'D',
F = 'F'
}
for (let grade in LetterGrade) {
console.log(grade);
}
The above will give us A to F, but what is below will give us 0 to 4 before A to F and then A to F as well.
enum LetterGrade {
A,
B,
C,
D,
F
}
for (let grade in LetterGrade) {
console.log(grade);
}
Model changes which are ultimately JSON changes will cause errors far downstream in an Angular app.
There is no real type safety in JavaScript in spite of how much TypeScript will have you believing that there is. If a type hydrated from an API call is supposed to be a number and you get an object instead the code won't blow up until you do something later on like try to run the number with the CurrencyPipe. It is a little tricky to put your finger on exactly what went South quickly.
ngrx/router-store
This sums itself up with "Bindings to connect the Angular Router to @ngrx/store" and is more or less a way to store router variables in the store so that your components may just read them from the store in lieu of from the routes.
Throw away all changes in Visual Studio Code 1.17.2.
At the icons at the upper left for Explorer, Search, Source Control, Debug, and Extensions, click Source Control and you should see a list of changes. If you mouse over each change you will see an icon for a counterclockwise turning circular arrow that you may click to roll back your change to no change. Bonus: If you mouse over the "CHANGES" title itself you will see a counterclockwise turning circular arrow for undoing all of the changes at once!
Try to make a:focus behave differently between tabbing to an a tag and clicking on an a tag.
This suggests a way to do it by dragging in jQuery. Basically you have to swap a CSS effect in and out based on whether or not you just had a keydown or click event.
Addendum 4/23/2018: Remember that you should write logic to specifically make sure that the tab key was pressed and not some other key. The following example is of Angular 4 not jQuery like the Stack Overflow article.
keydownEvent(event: KeyboardEvent): void {
if (event.keyCode === 9) {
this.isToShowOutline = true;
} else {
this.isToShowOutline = false;
}
}
Thursday, April 19, 2018
:nth-child(1n+0) instead of !important
Styling a tag more specific than the one you want to overpower instead of merely using the !important hack is probably a better way to get around a style blockade. There is a whole numeric scoring system for who wins in CSS collisions beyond merely inline styles beating ids and ids beating classes, and the more specific stylings beat those that are less so. By the way the an+b specification will style every Ath child starting at position b so in this case, every child.
Addendum 4/20/2018: This has some notes on the grading for the specificity rules.
MBTI and FFM
Myers-Briggs Type Indicator (MBTI) is the thing with Extraversion (E) versus Introversion (I), Sensing (S) versus Intuition (N), Thinking (T) versus Feeling (F), and Judging (J) versus Perceiving (P) personality typecasting. I remember grabbing lunch one day with Brad Coffman and Bryant "Poff" Poffenberger during the @hand days and they were off on a tangent about this. I have not heard of Five Factor Model (FFM) but it seems to try to figure out if your personality is one of Openness to experience (inventive/curious versus consistent/cautious), Conscientiousness (efficient/organized versus easy-going/careless), Extraversion (outgoing/energetic versus solitary/reserved), Agreeableness (friendly/compassionate versus challenging/detached), or Neuroticism (sensitive/nervous versus secure/confident). OCEAN and CANOE are acronyms for the five things. In chapter 1 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis MBTI and FFM are namedropped as the sample app that will be made throughout the book will be one of a free personality test (testmakerfree.com). I feel like I've already joined the Scientology cult! Xenu!
Wednesday, April 18, 2018
outline versus border in CSS
I ran into an outline in CSS today. Stack Overflow says:
- Outlines do not take up space.
- Outlines may be non-rectangular.
Can't bind to 'ngForOf' since it isn't a known property of 'div'.
Fix this problem by importing CommonModule in your module in an Angular 4 application.
import { CommonModule } from '@angular/common';
When styling Angular Materials components...
You may need to style the selector tag itself of the thing you are handing ng-content into. To do so just call out to the tag in CSS as you might any other tag such as div or p without a leading dot or hashtag. (It's not a class or an id.) You will notice the selector tags appearing in the markup that survives Angular's interpretation.
flex: 1;
In some of the modern flex CSS stuff this seems to be a setting governing reactivity of a flexible item. There are really three settings herein so I think...
flex: 1;
...is short for:
flex: 1 1 auto;
The three values here from left to right are flex-grow, flex-shrink, and flex-basis. The first two define how an element will shrink and grow relative to others in being flexible and last of these, flex-basis, is the length of an item. The length could be in percentage, pixels, or em or it could have an auto or inherit setting.
No store found. Make sure to follow the instructions.
When I see this error in the Redux pane of the Google Chrome Developer Tools, it is because I opened the pane after I loaded the URL. To fix this, all I have to do is refresh the browser.
Tuesday, April 17, 2018
The vw and vh units are like px and em in CSS.
They stand for viewport width and viewport height. 50vw would imply 50 percent of the viewport width.
Hashbang versus HTML5 History API
The pushState API is a way out of using the pound sign/numbers symbol/hashtag in routes. You can basically put things in and out of a history of URLs and you may change a URL without a page refresh along those lines. This is helpful for both a SPA (Single-page Application) and/or a NWA (Native Web Application), sort of a halfway step between an MPA (Multi-page Application) and a SPA wherein there are a few modules broken up across a handful of pages for the walloffable, independent chunks of an app and the modules are all little SPAs. This is more wisdom from "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis. This is in the first chapter.
Ctrl-Left-Arrow in Visual Studio Code 1.17.2 will allow you to walk backwards in the history of tabs.
That way if you control click to drill into references and open new tabs in doing so you can easily navigate back towards where you were, i.e. the right tab.
Addendum 5/17/2018: It's Alt-Left and not Ctrl-Left as it turns out.
Monday, April 16, 2018
modern interfaces and patterns in a SPA application
"ASP.NET Core 2 and Angular 5" by Valerio De Sanctis suggests on page 13 that staples include:
- HTML5 pushState API - set the history in window.history.back(); with tricks like this: history.pushState(stateObj, "page 2", "bar.html");
- webhooks - HTTP callbacks such as getting something back from a POST
- data transport-based requests - (talking to a REST API from the head of a headless app)
- dynamic web components - more...
- UI data bindings - *ngFor for example
- stateless, AJAX-driven architecture - speaks for itself
When you do a .dispatch off of an instance of Store as imported from @ngrx/store...
You don't have to have an effect which would have been found by the action you handed into .dispatch anyways. If you just have an action and a reducer you may write stuff to the store the Store instance references. The magic of how the action and reducer are found is somewhat out-of-sight/out-of-mind in the NgRx machinery.
304 Not Modified versus 200 OK
304 is telling you that the content has NOT changed since the last time you reached out to the URL.
the difference between .some and .every in JavaScript
.some returns true if one item in the collection matches the criteria, but .every only returns true if every item in the collection matches the criteria.
Sunday, April 15, 2018
Roslyn complies to CoreCLR
This instead of the CLR (Common Language Runtime) the .NET Framework stuff compiles to. RyuJIT is used instead of Roslyn for JIT (Just In Time) compilation. I suppose that is WebMatrixesque C# inline markup stuff. This all comes from page 10 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis.
Saturday, April 14, 2018
Who are the players in the server-side showdown?
Today I have finished reading the preface in "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis and, yes, this is worth mentioning and a real part of the book's 517 pages before the blank white page before the index. The pages are labeled with modern day numbers and not those funny Roman numerals or Egyptian hieroglyphics or whatever so it's legit, right? Things mentioned in the preface include WinRAR, 7-Zip for Windows, Zipeg, iZip, UnRarX for Mac, 7-Zip, and PeaZip for Linux which are unzipping tools, the .NET Core Windows Server Hosting bundle which when installed (Windows Server 2008 R2 is suggested for the platform) should allow one to host .NET Core at IIS which I suppose will not just happen out of the box, PathLocationStrategy which extends LocationStrategy and seems to, at a glance, allow for URLs with a leading backslash to use some route other than the most minimal one as the base URL, database management system (DBMS)-based Data Models of Entity Framework which have an Entity Data Model (EDM) shape matching one-for-one database columns in tables, Angular Template Syntax as a formal name for the markup in component templates, and the Angular Model-Driven approach as sort of a rationale in buzzword form for the reactive forms that everyone hates. There is a big opening about how exciting the frontend space is right now, and, then, almost as an afterthought, the race to make things better at the server-side is mentioned too. Java and Ruby are not mentioned at all. The author seems to see three big players. Surprisingly one of them is PHP due to some modern frameworks:
So what are the other two platforms worth caring about beyond PHP? Well, it probably won't surprise you to learn that ASP.NET Core makes the list. The book mentions that its run-anywhere nature (demanding a complete rewrite of the ASP.NET Framework) now runs on not just macOS but also:
- Debian
- SUSE, an operating system OS built on an open-source Linux kernel wherein the name stands for "Software und System-Entwicklung" German for: "Software and systems development"
- ARM32-native builds for Raspberry Pi (ARM stands for Advanced RISC Machine and originally Acorn RISC Machine wherein RISC is: reduced instruction set computing)
Finally, we have Node as the third player. The book namedrops a few things for the Node space and amongst them AdonisJS, a UI framework, was the only one I had not heard of before.
Friday, April 13, 2018
What is the Reactive Manifesto?
I am starting to read "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis which just arrived on my doorstep today. I have only read the first page. The first page namedrops The Reactive Manifesto which is the first new thing I have learned. This is a high level spec for what progressive web apps should be. They should be:
- Responsive
- Resilient, i.e. replication, containment, isolation, delegation
- Elastic (sharding and load-balancing and the like / resources managed well)
- Message Driven
don't try to paste short codes for emoticons into Lync
(x) will make a little girl with pigtails when you just type it in, but not when you copy and paste it!
.some versus .find versus .filter versus .map in JavaScript
I found these starting to blur together some for me and so a cheatsheet is in order, right? Let's assume we have an array of cats in a variable called cats...
- .some will return a true or false value for if any one item in a collection meets a condition, say for example if any one of the cats has all nine lives left and you may put verbose rules in .some so while you are finding the first match and doing nothing with the Boolean being returned you could also trigger other methods or set some state somewhere
- .find will find the first match so we could find the first of the cats that still has nine lives
- .filter will create a new array from an array with only the items surviving the trip that match a condition so we could filter all of the cats from cats which have nine lives left into a fullyCharged array
- .map will allow us to transform every object in the array, turning cats into ostriches, while also filtering too if we like based on the conditions of our choosing (The rules inside of .map may be verbose and you could turn some of the cats into ostriches and some of the cats into walruses while having the ostriches and walruses end up sprinkled into the same collection together. Pragmatically, this sort of transformation would be better served by two separate mapping operations in which some filtering also occurs putting just the ostriches in one array and just the walruses in another array.)
- .forEach ...I don't really need to tell you what this does do I? I'm not sure if it returns anything. Maybe it just returns the same array. The .forEach (and/or the lambda in TypeScript) allows you to doctor up every item in an array so we could spay and neuter our cats.
Addendum 4/19/2018: Since writing last I have realized that .every should really be mentioned above and that it may be best to try to transform inside of a .filter instead of selectively return inside of a .map as if you try to just not return something in a .map loop you may end up with a null value sprinkled in your array.
Addendum 4/23/2018: I have learned today that you really cannot doctor stuff up with .filter like .map and what is more you really only want to return true or false from within a filter's loop. If you need to both map and filter you need to chain the two operations as best as I can tell. Also, note that you may pass an index in these loops as a second variable after the item at hand. Behold:
let yin = [13, 42, 69, 23];
let yang = [27, 42, 69, 86];
let venn = yin.map((y, index) => {
if (yin[index] != yang[index]) return index;
}).filter(x => {
if (x || x === 0) return true;
});
console.log(venn);
Addendum 5/1/2018: There is also a .find which does the same thing as .filter only instead of returning a collection it returns the first match. There is a .reduce too which is just crazy.
"The wrapper" is a pretty good pattern for generics.
Let's say I want to have a type and then an isDirty flag with it. Well I could write a type that has T for the wrapped type, Cat, Dog, or Person or whatever, and have a getsetter for the Boolean for isDirty right? If I want to have a serializable type make its way from C# to JavaScript and also carry with it a ruleset for the RegEx for sanity checks for the fields at the forms to be used at the JavaScript side of things, that could look like a wrapper with T for the type and a getsetter for a Dictionary<string,string>. What is more, that same wrapper would work pretty good for a collection of things beyond a single item too.
Thursday, April 12, 2018
Negative right margins are legit.
Do you know how you may set a negative top margin on a div to make it sort of sit a few pixels on top of the thing that is pushing it down to where it is? ...and, for that matter, how you may set a negative left margin to pull a div a bit leftward from whatever it is pressed against at its left? Negative bottom margins behave kinda strangely, huh? It is akin to putting the same setting for a negative top margin to the div below the div you are styling. Anyhow, I experimented today with a negative right margin! I had a div sitting inside of another div which had both a reactive flexible width that could vary with the browser's width and ten pixels of padding on the right and left side. I needed the nested to div to be a different color for a callout at the base of a content area and also really run edge to edge of the div it sat in, ignoring the fact that it would be otherwise scrunched by the padding. The fix was to set a negative left margin and a negative right margin of ten pixels each at the nested callout div. The right margin makes the div jut rightward past its rightward bounds a number of pixels that is the reciprocal of its negative number, ten.
Wednesday, April 11, 2018
The searching in Visual Studio Code 1.17.2 plays nicely with snake case!
Pressing Ctrl-P and searching for mdhf should help you find my-dog-has-fleas.component.ts while the last key down, the f, will filter away my-dog-has-cancer.component.ts as an option.
The first variable in the .navigate off of the Router of @angular/router can concatenate an array of strings for a URL.
this.router.navigate([this.foo, this.bar], { relativeTo: this.baz });
So if foo above holds /recreation/companionship/pets/ and bar holds "kittens" then we are going off to http://www.example.com/#/recreation/companionship/pets/kittens alright? What is above kinda assumes wireups like so:
- import { Router } from '@angular/router';
- constructor(private router: Router) {
A way to do this sort of thing inside of an HTML tag in a template is like so:
<a [routerLink]="[this.foo, this.bar]">
Get out of using any to fish out event.target.value in a (change) event in an Angular 4 application.
If you have a control like so:
<input type="text" (change)="updateField($event)" />
You are probably used to doing this:
whatsInTheBox(event: any) {
const content = event.target.value;
alert(content);
}
But, you could do this instead:
whatsInTheBox(event: Event) {
const control = <HTMLInputElement>event.target;
const content = control.value;
alert(content);
}
Note that you cannot dot dot dot out to event.target.value with an Event. You have to cast HTMLInputElement, also, this seemed to work when tabbing away with a KeyboardEvent which is one of many events that implements Event per this but I wondered if when I clicked away instead of tabbing away if I should be using MouseEvent. It seemed to work, the mousing elsewhere with KeyboardEvent, but I wonder if that is just because type safety is all a placebo in TypeScript. Anyhow, if both things inherit from Event why not just use Event if Event has .target hanging off it?
how to hand a style into ng-content injections
<div>
Look at this graph:
<nickelback [details]="'data'" [width]='3'>
<h1>Whatever</h1>
<span class="date-italic">since 1995</span>
</nickelback>
</div>
Where will we define date-italic? In the nickelback component itself? That would defeat a lot of the point of injection, huh? No, you don't have to do it there. The same component that has the markup seen above, the one that has the nickleback selector tag inside of its template, should also define date-italic at it's CSS file! Part of the magic of ng-content is that this will work without the ::ng-deep hack!
Check to see if two objects have the same reference in JavaScript!
Do a strictly equals comparison with the === operator between the two objects. It won't matter is some of the properties have been changed on one of two matching actors because really if they have the same reference they both have the change as they are both the same thing with the same reference/pointer. Get it? Sometimes this trick makes more sense than explicitly putting id properties at objects to tell apart the contents of a collection. In the NgRx paradigm in an Angular 4 app wherein you do not wish to mutate state, EVER, how will you update just one piece of an array with a .map operation?
updateAttitudeAction = <UpdateAttitudeAction>action;
return {
...state,
attitudeAndAdvocacy: {
...state.attitudeAndAdvocacy,
attitudes: state.attitudeAndAdvocacy.attitudes.map(a =>
a === updateAttitudeAction.attitudeReference
? { message: updateAttitudeAction.updatedAttitude }
: a
),
isDirty: true
}
Tuesday, April 10, 2018
Assignments from a variable to a property of the same name at an object may be simplified in TypeScript.
let foo = 13;
let bar = 42;
let baz = 69;
let qux = 86;
let whatever = {
foo,
bar,
baz,
qux
};
console.log(whatever);
...is the same as...
let foo = 13;
let bar = 42;
let baz = 69;
let qux = 86;
let whatever = {
foo: foo,
bar: bar,
baz: baz,
qux: qux
};
console.log(whatever);
The former in TypeScript will make the later in JavaScript.
console.log("foo", foo);
When the foo object gets logged to the console in JavaScript, the word "foo" will appear by it's arrow to expand it and see its guts in Google Chrome Developer Tools.
.find in JavaScript
This has this example which returns the first match for a condition, in this case the number 12.
var array1 = [5, 12, 8, 130, 44];
var found = array1.find(function(element) {
return element > 10;
});
There is a CurrencyPipe built into Angular 4 for formatting numbers as dollar values.
xunit
In chewing on the problem I mention at this blog posting, I realize the link at the top of the blog posting suggests that I use xunit to run tests to get around the brick wall I have been hitting in an inability to run tests. So that means that steps 9 and 10 get replaced with:
- install-package xunit YourTestProjectNameHere
- install-package xunit.runner.console YourTestProjectNameHere
Also the top of my test changes like so:
using System.Collections.Generic;
using GroverClevelandHopscotch.Core.Interfaces;
using GroverClevelandHopscotch.Core.Objects;
using Moq;
using Xunit;
using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
namespace GroverClevelandHopscotch.Core.Tests.Objects
{
public class PresidentTests
{
[Fact]
public void FlatFileMechanics_do_return_Presidents()
{
Great, but I still can't get it to work. I get this error:
No executable found matching command "dotnet-xunit"
Make the NuGet packages for a .NET Core project in a .NET Core Solution publish out to the bin folder upon a build.
Open the .csproj file for the project and put...
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
...inside of the PropertyGroup tag.
Monday, April 9, 2018
I am trying to set up Moq for mocking in .NET Core!
Per this and my own Visual Studio 2017 tinkerings:
- Go to: Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
- Click the gear at the upper right.
- When the "Options" dialog box appears, click the giant green plus symbol to add an available package source.
- Add a source to: https://www.myget.org/F/aspnet-contrib/api/v3/index.json
- Close the "Options" dialog.
- Go to the "Browse" tab, click the "Include prerelease" checkbox, and select your package source from the "Package source" dropdown list.
- Search for "moq.netcore" and install it!
- Go to: Tools > NuGet Package Manager > Package Manager Console
- Run: install-package System.CodeDom YourTestProjectNameHere
- Run: install-package System.Security.Permissions YourTestProjectNameHere
- Then what?...
I get this error:
The type initializer for 'Moq.Mock`1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Moq.Proxy.CastleProxyFactory' threw an exception. ---> System.MissingMethodException: Method not found: 'System.Security.PermissionSet System.AppDomain.get_PermissionSet()'.
When I attempt to run a simple test like so:
using System.Collections.Generic;
using GroverClevelandHopscotch.Core.Interfaces;
using GroverClevelandHopscotch.Core.Objects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace GroverClevelandHopscotch.Core.Tests.Objects
{
[TestClass]
public class PresidentTests
{
[TestMethod]
public void FlatFileMechanics_do_return_Presidents()
{
//Arrange
Mock<IFlatFileMechanics> presidentialMock = new Mock<IFlatFileMechanics>();
presidentialMock.Setup(x => x.GetPresidents()).Returns(new List<President>()
{
new President()
{
Name = "Grover Cleveland",
Party = "Democrat",
HasNonconsecutiveTerms = true,
},
new President()
{
Name = "Benjamin Harrison",
Party = "Republican",
HasNonconsecutiveTerms = false,
}
});
//Act
List<President> presidents = presidentialMock.Object.GetPresidents();
//Assert
Assert.AreEqual(presidents.Count, 2);
Assert.AreEqual(presidents[0].Name, "Grover Cleveland");
Assert.AreEqual(presidents[0].Party, "Democrat");
Assert.IsTrue(presidents[0].HasNonconsecutiveTerms);
Assert.AreEqual(presidents[1].Name, "Benjamin Harrison");
Assert.AreEqual(presidents[1].Party, "Republican");
Assert.IsFalse(presidents[1].HasNonconsecutiveTerms);
}
}
}
rename a branch in the Git Bash command line stuff for Git
git branch -m oldnamehere newnamehere
Addendum: 4/11/2018: You can leave off the old name altogether if you are on the branch that is getting the renaming.
Make the first letter of some copy bigger with CSS.
h2 {
color: #883322;
}
h2::first-letter {
font-size: 30px;
}
Sunday, April 8, 2018
How do I hand a template and data into an Angular 5 component separately and then get the template to play nicely with the data?
I found a way. I made the default new application with the Angular CLI. In the token template, app.component.html, I added the following at the very bottom:
<new-stuff [dataPoints]="['foo','bar','baz','qux']">
<ng-template #templateReference let-handIn>
<strong><em>{{handIn}}</em></strong>
</ng-template>
</new-stuff>
Alright, for this to work, we need a new component to hand stuff into. I made such a component and just called it NewComponent and it looks like this:
import { Component, ContentChild, TemplateRef, Input } from '@angular/core';
@Component({
selector: 'new-stuff',
templateUrl: './new.component.html'
})
export class NewComponent {
@Input('dataPoints') data: Array<string>;
@ContentChild('templateReference', {read: TemplateRef}) templateInstance:
ContentChild;
}
We should loop NewComponent in at our module. Finally, the template for NewComponent looks like what follows. Note that we don't explicitly need the ng-content tag here as we are just handing in a template as content and if it does not explicitly get spat up in the markup of the component it will still behave as a template and tie into the ContentChild variable.
Look at this:
<ol>
<li *ngFor="let datum of data">
<ng-container *ngTemplateOutlet="templateInstance; context: {$implicit: datum}">
</ng-container>
</li>
</ol>
<ng-content></ng-content>
If we want to get away from the $implicit binding we could put this at the footer of app.component.html.
<new-stuff [dataPoints]="['foo','bar','baz','qux']">
<ng-template #templateReference let-handIn="communicatedValue">
<strong><em>{{handIn}}</em></strong>
</ng-template>
</new-stuff>
NewComponent's template would thus change like so to accommodate at much.
Look at this:
<ol>
<li *ngFor="let datum of data">
<ng-container *ngTemplateOutlet="templateInstance; context: {communicatedValue:
datum}"></ng-container>
</li>
</ol>
<ng-content></ng-content>
data URLs
In the default Angular CLI new app we have inside the token template:
<img width="300" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
This basically put the gobbledygook that would make up an image file (ever open a .jpg in Notepad?) hosted independent of the template just inline right there in the template. This is kinda a bad example because what is above seemed to be SVG and not a .jpg. A .jpg example would start out like so I think...
data:image/png;base64,
...or is that a .png? :P
Error: Cannot find module '@angular-devkit/core'
Fix this problem with:
npm i -D @angular-devkit/core
Create a new Angular project with the Angular CLI.
ng new yournamehere
...is the command to run at the command prompt to get this to work. I'm not yet sure what brings ng new in scope to make it accessible for use. Maybe if you install the CLI at a different project it puts the feature in whatever must be a global registry for np commands. I dunno. I'm just guessing.
Install the Angular CLI at an Angular project.
Navigate to a folder holding package.json at the command prompt at Windows 10 (while running as Administrator) and type:
npm install -g @angular/cli
Saturday, April 7, 2018
When you accidentally archive a photo instead of deleting it on Instagram...
- Go you your profile by clicking the icon at the lower right of the main navigation that looks a head and shoulders.
- Click the icon at the upper right that looks like an arrow going in a circle counterclockwise with clock hands inside of it.
- At the top of page that appears that says "Archive" click on the "Archive" title to get options.
- Amongst the options are "Posts" and you should pick that.
- Delete the thing you archived.
Friday, April 6, 2018
the difference between "To Do" and "Open" in Jira's machinery
This suggests "To Do" is a status category and "Open" is an issue status. The link I give here is not user-friendly but it vaguely feels as though "Open" is one of several issue statuses that could be of the "To Do" status category.
The active part of LoVe and HAte in CSS will define how a button looks when clicked.
See this for more. An example might be:
.whatever:active{
background-color:#123456;
}
What does LoVe and HAte have to do with Darth Vader?
"King Philip came over from Germany Saturday." That is how we were taught to remember Kingdom, Phylum, Class, Order, Family, Genus, Species ...in my high school Biology class. Similarly, this has "Lord Vader’s Handle Formerly Anakin" and "Lord Vader Hates Furry Animals" as ways to remember the link pseudoclasses: :link, :visited, :hover, :focus, :active ...this is new because focus is new. It is a way to set the style of something upon what happens when you tab to it like so:
.whatever:focus{
background-color:#123456;
}
LoVe and HAte used to be the way to remember before focus. See this for what LoVe and HAte used to be.
Thursday, April 5, 2018
long lasting subscriptions with NgRx?
Observables can listen to a web socket right? This is how the long life thing was original explained to me and before my immediate role I would have rolled my eyes and said: "When will I ever talk to one of those?" as in just speaking to an API endpoint the only things I need to do with Observables are things I can just do with promises anyways, right? An API endpoint is not going to tell you something twice so why would you ever do a .subscribe when one can just to a .toPromise().then instead? All I ever interact with is REST APIs. I've never worked anywhere where they have web sockets going on and I still don't. However we are using the Redux store and there are times when data changes in long life. Imagine:
- In spinning up an app we call an API endpoint to get all of our Cats.
- Before the promise from the API comes back we are hitting ngOnInit in outermost component in our Russian Doll hierarchy, a smart component, and also the constructor where a resolver is handing in the data context for the store. In ngOnInit we map off a Cats variable, but at this moment in time there are no Cats!
- We hand a Cats | async onto the first dumb component nested in our smart component.
- We display Cats[0]?numberOfLives in the template, but at first this gives us nothing.
- The API promise comes back.
- The store gets updated with thirteen beautiful Cats.
- Change detection triggers the subscription in Cats back at the smart component to update that which the Observable wraps, the meat of data.
- Change detections hands Cats down the Russian Doll chain.
- At the template of the component that is one component deep we see the number 9.
As we do CRUD operations to the Cats and go the API and back the store similarly updates. The use of the async pipe to hand a subscription's sweet stuff on to a second component is a pretty good pattern herein. The async pipe and doing a .subscribe off of params in the routing paradigm are, I think, the only two examples of .subscribe that will clean then themselves up when unused without creating a memory leak or causing you to explicitly destroy them with an .unsubscribe at an ngOnDestroy.
Addendum 9/17/2019: Here I uncover a third scenario in which you do not have to unsubscribe to a subscription.
If you type the designation for an HTML tag without the angle brackets around it and then double-click the tab key in Visual Studio Code 1.17.2...
It will make an open and close tag for you. For example p-Tab-Tab makes: <p></p>
Use just Headers and not HttpHeaders with HttpClient in an Angular 4 application.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../../configuration';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import { President } from '../models/president.model';
import { PresidentialContract } from '../contracts/presidential.contract';
@Injectable()
export class PresidentialService implements PresidentialContract {
constructor(private http: Http, private httpClient: HttpClient, private configuration:
Configuration) { }
getPresidents():Observable<Array<President>>{
let route: string = this.configuration.routeToApi + "api/president";
return this.httpClient.get<Array<President>>(route,{});
}
setPresidents(presidents:Array<President>):Observable<any>{
let route: string = this.configuration.routeToApi + "api/president";
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.put(route, presidents, options).map((response: Response) =>
<Boolean>response.json());
}
}
I guess to solve the problem mentioned here this...
let headers = new Headers({ 'Content-Type': 'application/json' });
...could become...
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
This has a little cheatsheet on the Content-Type possibilities. This has a cheatsheet of what all of the request fields beyond and including Content-Type are. I guess if we wanted to get some XML back from our requests our headers could be like so:
let headers = new Headers({ 'Accept': 'application/xml',
'Content-Type': 'application/json' });
The order of the headers should not matter.
A double pipe in JavaScript can be used like the ?? null coalescing operator in C#.
var whatever = function(yin) {
return yin.yang || new Yang();
}
If the fat arrow inside of a .then in TypeScript has only the one line for returning something, you don't need to wrap the line in curly braces or use the return keyword.
This...
.then(x => new Whatever(x));
...does the same thing as this:
.then(x => { return new Whatever(x); });
Addendum 4/6/2018: Remember if you do this simplification trick when newing up an object with curly braces that you need to wrap the curly braces in parenthesis. So this...
.then(x => { return {'foo':'bar','baz':'qux'} });
...becomes...
.then(x => ({'foo':'bar','baz':'qux'}) );
NgRx selectors
In a Redux selector in an Angular application one hands in at least one function that returns a stateful object and then gets back a function that returns an object like so:
import { DataContext, MyStateModel } from '../data-models';
import { createSelector } from '@ngrx/store';
export const getStuff = function (state: DataContext) {
return state && state.myState ? state.myState : new MyStateModel();
};
export const getSpecificStuff = createSelector(
getStuff,
(x: MyStateModel) => {
return x.mySpecificState;
}
);
The last argument defines the shape of what should be handed back. The preceding argument in the example above is a function returning state, but it should be noted that there could be n number of these handed in before the definition for what should be returned including other selectors. You may hand selectors in as the leading arguments into other selectors and in this manner drill down to the data you want. Note that if there were two upfront arguments there would also be two variables in the signature of the last setting as well.
Wednesday, April 4, 2018
add a filter in Jira!
Assuming the interface of the moment at Jira on 4/4/2018:
- Go to "Issues" by clicking the icon at the far left of the browser which looks like a magnifying glass inspecting four horizontal lines.
- Click "View all issues and filters" at the upper right.
- Click "New filter" at the upper left.
- Change around the controls in a horizontal row below the word "Search" as needed. For example, in typing this up I opened up "Status" and checked the checkboxes for "Open" and "In Progress" to make a filter that will only show these statuses.
- Click "Save as" by "Search" to save.
- You will be prompted to give a name for your filter. Give a name.
- Your filter should appear under the list of "Favorite Filters" at the lower left.
There will be an "Advanced" link at the upper right that when clicked turns into a "Basic" link to toggle back out of "Advanced" and when things are basic the WYSIWYG controls show and when things are advanced you will have the ability to type some query syntax like so:
status in (Open, "In Progress")
Resolve in the Angular 4 paradigm should allow you to hand state on to a component.
Assuming a routing module like so:
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { WhateverComponent } from './components/whatever.component';
import { WhateverResolverService } from './services/whatever-resolver.service';
export const PlanRoutes: Routes = [
{
path: 'yin/:yang',
component: WhateverComponent,
resolve: {
'whateverResolver': WhateverResolverService
}
}
];
@NgModule({
imports: [
RouterModule.forChild(PlanRoutes)
],
exports: [RouterModule]
})
export class WhateverRoutesModule { }
One should be able to have a WhateverResolverService to hand a DataContext, fished out of an NgRx store, on to WhateverComponent by crafting something like this:
import { DataContext } from '../../../../whatever/data-models';
import { WhateverAction, getStuff } from '../../../../whatever/store';
import { Observable } from 'rxjs/observable';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { Store } from '@ngrx/store';
import 'rxjs/add/operator/take';
@Injectable()
export class WhateverResolverService implements Resolve<any> {
constructor(private router: Router, private store: Store<DataContext>) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<any> {
const yang = route.params["yang"];
this.store.dispatch(new WhateverAction(yang));
return this.store.select(getStuff).take(1);
}
}
You will notice that we make use of the yang parameter to go fishing for our data. I was surprised to see that this not like the typical routing snapshot which represents how the route first was and will not reflect updates. Instead, every time the route changes, the resolver will run once. Nice! At the constructor of WhateverComponent we could have something like private store: Store<DataContext> to catch what the resolver hands in. This is an example of a long lingering Observable too. The only one I have every used myself. For all of talk of how one could use an Observable to listen at a web socket and be constantly updated, for the most part I have just interacted with API endpoints and have only done things with Observables that could be done with promises. This is the next level stuff. Forgive the use of "next level" as I know that's all-too-modern slang. WhateverResolverService needs to be looped in at providers at the applicable module.
Addendum 4/5/2018: What I say above out catching a DataContext at the constructor of the component is wrong. Sorry, I am dealing with an NgRx store at work. Instead you could have a component constructor as follows and do note the reuse of "whateverResolver" too.
constructor(private activatedRoute: ActivatedRoute) {
this.activatedRoute.data.subscribe(theCaught => {
console.log('look at this:');
console.log(theCaught.whateverResolver);
});
}
If this were the end of the resolver...
const simpleObservable = new Observable((observer) => {
observer.next({ 'foo': 'bar', 'baz': 'qux' });
observer.complete();
});
return simpleObservable;
}
}
...then we would be able to log to the console the foo/bar/baz/qux object alright in this approach.