- TemplateRef and NgForOfContent are keywords for the templating stuff in Angular 4.
- VAR is an old acronym for value-added reseller, a company who will both sell you computers and set up your LAN for you in lieu of just selling you computers alone. In both cases the selling of computers is a reselling as the computers would have originally been bought up from Dell or HP or Gateway or whatever.
- Flickr lets you host images/video.
- Shockwave allowed you to run Macromedia Director movies at the web.
- In a bait and switch tactic an employer tells a would-be-employee about how great the job is and when the employee shows up for work they learn within a month that they've been lied to.
- Exago has tools for making SSRS reports and has extra charts and graphs, etc.
- bmovies.se is a web site that has, yes, a catalog of old B movies, but, also, A list modern movies. Anything out in the theaters for a day has a ghetto bootlegging up on bmovies.se and anything that has been out for a month has a grade A pirated copy there.
- Koa is another server thingy for Node like Express or Hapi.
- ls in FreeBSD stands for "list segments"
- Leet is the art of replacing some letters with numbers that kinda look like the letters. l33t is leet for leet. (leet comes from "elite")
- Epic in an Agile sense is something bigger than a story that ideally should be broken up into stories.
- AltaVista is an old search engine.
- HTTP_PROVIDERS was something that showed up in the early Angular 2 code and was gone in later minor version releases of Angular 2 and certainly before Angular 4. If you Google this you can still find weird Stack Overflow references to it. It's deprecated.
- Project Jigsaw is an exercise to find standards for the Java SE 9 Platform and the JDK (Java SE Development Kit) with it. SE stands for Standard Edition here.
- DBA stands for either "doing business as" or "database administrator" if a person is a DBA.
- _extend is a lodash thing
- RubyGems is package management stuff for the Ruby space.
- Duda is a rival for WordPress.
- Longhorn was a codename for Windows Vista.
- Weedmaps is a mobile app for finding pot (marijuana) in California.
- The EU General Data Protection Regulation (GDPR) is a standard for handling data which includes a lot of privacy things like a right to be forgotten.
- A .bat file is a batch file. (.bat stands for batch)
- POC stands for proof of concept.
- Lightbox, as a feature, would suggest a place where photos are collected in an application. Maybe a place where you may next, next, next through your photos.
- LG G Flex is a self-healing phone! There is some sort of polymer that is being stretched for the screen and scratches will eventually flatten out to not scratches.
- bovada.lv (Latvia) is a site for sports betting
- In a list of to-dos the "low-hanging fruit" is the subset of the to-dos which are easiest.
- Sina Weibo is a microblogging (think Twitter) platform that is big in China.
- Watir, which is kinda like WatiN, is for the Ruby space.
- Wikipedia suggests that TWAIN is an API that bridges some gaps between software and "digital imaging devices" and I associate TWAIN with using a scanner at a FedEx Office.
- OCI or (Object Computing, Inc.) has its hand in "Groovy on Rails" or Grails which is also really open source.
- JUG stands for Java User Group.
- copied from Wikipedia: "WebP is an image format employing both lossy and lossless compression."
- There is the concept of meta-reducers which are reducers for reducers in the ngrx/store paradigm.
- There is a new view renderer coming in Angular 6 that you have to turn on application-wide with a flag. This is the big difference between 6 and 5. In 5 you got the beta of the CDK and Angular Materials which is the big difference from Angular 4.
- Chelsea Manning gave state secrets to Julian Assange.
- Symantec AntiVirus is some antivirus software like Norton AntiVirus.
- WLAN means Wireless LAN (Local Area Network).
- I'm hearing secondhand that a lot of Telerik controls are bug laden and even have bugs that have been left to sit for years without anyone circling back to them.
- A white label product is a product easily reskinnable that could be rolled out for different businesses with their branding and logos and color schemes.
Saturday, March 31, 2018
March Queso
Friday, March 30, 2018
smells and stamps
On Monday night I saw Clint Edmonson speak at that Saint Louis .NET User Group on code smells. Consistent with a format that that Saint Louis .NET User Group seems to have adopted just this year, there was a lightning talk before the real show began and this time around an Alan Barasch gave us a PowerPoint presentation on his stamp collection. Before Alan got started, the powers that be asked the audience "Who likes the new format?" (paraphrasing not verbatim) with the lightning talk lead-in and I did NOT put my hand up, and then once Alan got started with his stamps I was kinda rolling my eyes and thinking "Fast Forward!" but the surprise of the night was that he ended up having the better of the two talks. A lot of the "great names" of computer science have been honored on stamps either in the U.S. or elsewhere and so there was a little bit of history on the "great names" of which I had not heard of quite a few. Charles Babbage was credited by Alan has having invented the first computer in the 19th century. Herman Hollerith did some punchcard (or is it punched card or punch card?) programming for the 1890 U.S. census. Jack St. Clair Kilby created the first integrated circuit (microchip). John von Neumann was a pioneer in quantum mechanics (mathematical descriptions of motions, the codification of an act of science) and I think Alan associated CRTs (cathode ray tube) with him though my own notes are a little fuzzy. Alan suggested Rear Admiral Grace Hopper was really the first coder and certainly I had heard of her before. The rumor or reality that the term "debugging" comes from her literally removing the corpses of insects that had flown into machines to get some big apparatus full of vacuum tubes to run better was my prior understanding of her place in history. Tom Watson of IBM and Alan Turing were also namedropped and I had heard of them. Jack Saint, Jon Von, Babs, and Holly were all new for me. The Clint Edmonson talk went through a list of common smells. Don't write your own gunk to empower a semaphore, a mutex, or a critical section. Going there smells of NIH (not invented here) syndrome in which a developer doesn't trust anything third party. Beware of marathon methods. The longer a method is the more likely it is to break with the DRY principal. And so on... Two new terms (new for me) that were namedropped along the way in the talk were CRC and PDL. CRC would be class/responsibility/collaborators and you would make CRC cards, literally index cards that you would scribble on with a sharpie or whatever, in the name of some in-house documentation in the name of preventing marathon methods. One card per one class would be the way the cards would take shape I suppose. For a class you would list, you guessed it, the class, the responsibility, and the collaborators. Clint mentioned CRC cards as if remember something he had not seen in years. PDL is program description language and this takes shape in writing comments on what a method should do before you fill in the method with what it should do. Again, this is to prevent marathon methods. I am NOT suggesting PDL is recommended.
Thursday, March 29, 2018
Update two different router-outlet tags in an Angular 4 application.
In this markup, the first tag below is the primary router-outlet behaving as you'd expect and the named router-outlet is a second router-outlet.
<router-outlet></router-outlet>
<router-outlet name='myOutlet'></router-outlet>
Hit both of these at once at http://localhost:4200/#/whatever/foo/(myOutlet:13) with routes like so:
export const PlanRoutes: Routes = [
{
path: 'foo/',
component: MyComponent,
resolve: {
'businessPlanningResolver': BusinessPlanResolverService
},
children: [{
path: ':id',
component: MyOtherComponent,
outlet: 'myOutlet'
}]
}
];
Did you know you may have activate and deactivate events at a RouterOutlet tag in an Angular 4 app?
This has this example:
<router-outlet
(activate)='onActivate($event)'
(deactivate)='onDeactivate($event)'></router-outlet>
Wednesday, March 28, 2018
NavigationEnd
This has the following example of getting a NavigationEnd from the Router (where both things import from @angular/router):
this.router.events
.subscribe((event) => {
if (event instanceof NavigationEnd) {
console.log('NavigationEnd:', event);
}
});
NavigationEnd is an event that happens at the end of a navigation. It is a late-in-the-lifecycle lifecycle event for routing.
translateX and translateY are another way to move things about horizontally or vertically in CSS
change where Node tries to run Node from
set path=%path:C:\Program Files (x86)\CA\SharedComponents\PEC\bin;=%;C:\Program Files (x86)\nodejs;
An Observable pipe, not to be confused with an Angular pipe, allows for outside pure functions to be used in midstream mapesque transformations.
Stack Overflow here has the following example which both returns the number fifty and seems to have some missing semicolons.
const { Observable } = require('rxjs/Rx')
const { filter, map, reduce, } = require('rxjs/operators')
const { pipe } = require('rxjs/Rx')
const filterOutEvens = filter(x => x % 2)
const doubleBy = x => map(value => value * x);
const sum = reduce((acc, next) => acc + next, 0);
const source$ = Observable.range(0, 10)
source$.pipe(
filterOutEvens,
doubleBy(2),
sum)
.subscribe(console.log);
nullable route path in an Angular route?
No, you may not make a chunk of the route nullable. You just have to have alternate routes for the permutations that might be given whether or not that route chunk is there.
params.subscribe auto-cleanup like the async thing
As this blog posting explains in its first two bullet points myRouter.snapshot.params is a list of parameters at the moment myRouter was spun up and you may get at these without a .subscribe, but you have to use a .subscribe to get at myRounter.params which reflect accurately updates to the params over time. The params will not include route chunks you may have at with Location. The params .subscription will automatically clean itself up when the route is dropped. You don't need to do the ngOnDestroy thing.
Use the Location in @angular/common to get the route/URL as a magic string in Angular 4!
Import:
import { Location } from '@angular/common';
Fish out what you need like so:
constructor(location: Location) {
this.whereAmI = location.path();
}
Tuesday, March 27, 2018
sickly secondary routing?
If you have outlets in Angular 4 routing denoting secondary routes you may, as mentioned here run into a sinister caching of the secondary routes as defines in outlets like so:
this.router.navigate([this.baseUrl, { outlets: { dialogOutlet: [this.answer.questionId], confirmOutlet: null } }]);
This fix in Angular 4 is to use a change of primary routing to account for sickly secondary routing when the cache has to be dropped. A lot of secondary route variables have a leading colon before them distinguishing them as variables from mere route chunks.
ERROR Error: Uncaught (in promise): Error: Cannot activate an already activated outlet
If you have outlets in Angular 4 routing denoting secondary routes you may, as mentioned here run into a sinister caching of the secondary routes as defines in outlets like so:
this.router.navigate([this.baseUrl, { outlets: { dialogOutlet: [this.answer.questionId], confirmOutlet: null } }]);
This fix in Angular 4 is to use a change of primary routing to account for sickly secondary routing when the cache has to be dropped. A lot of secondary route variables have a leading colon before them distinguishing them as variables from mere route chunks.
ERROR Error: Uncaught (in promise): Error: Cannot activate an already activated outlet
I have read online that this in an Angular app's package.json (at I guess "dependencies") might help fix this problem...
"@angular/platform-browser": "^4.4.6",
"@angular/platform-browser-dynamic": "^4.4.6",
"@angular/platform-browser/animations": "^4.4.6",
Only you wouldn't use version 4.4.6. This should really go in an Angular 5 app and I'm not working with Angular 5 so I can't get past an error reading...
npm ERR! Invalid package name "@angular/platform-browser/animations": name can only contain URL-friendly characters
Monday, March 26, 2018
How do I shake off the current folder when navigating away with Angular's routing?
When this...
<ol>
<li><a [routerLink]="['./','baz']">Baz</a></li>
<li><a [routerLink]="['./','qux']">Qux</a></li>
</ol>
...ends up causing a console error suggesting that a path to /foo/bar/qux/baz or /foo/bar/baz/qux is illegit, try this instead...
<ol>
<li><a [routerLink]="['/foo/bar','baz']">Baz</a></li>
<li><a [routerLink]="['/foo/bar','qux']">Qux</a></li>
</ol>
...which should give the desired paths to /foo/bar/baz and /foo/bar/qux
Avoid having stuff float right if you can help it.
A series of controls all with float: right; on them will have a non-intuitive tab order going right to left.
What do I keep when I merge?
Try to go line by line erasing a line out of one of the deltas, and keeping only what is different between the two. Then, hopefully it should just be a matter of keeping what you didn't delete and the stuff in the delta you haven't erased lines of code out of. Clearly the stuff from the trimmed down delta needs to be spliced into the right place in the otherwise unmolested delta. The problem with this of course begs the question "What if something was legitimately deleted?" and that can be the very hardest thing to see when doctoring merge conflicts together. I have readded code that was supposed to be destroyed before.
Saturday, March 24, 2018
I saw Jack Frosch speak on Groovy and Grails at the STL Angular Meetup on Wednesday night.
That doesn't really sound like an Angular talk, huh? It really wasn't. Jack tried to tie the talk into Angular as a subject by drawing a comparison between Groovy and TypeScript which as languages have some similarities. Also, Grails as a web framework has an easy to see parallel to .NET Core Controllers or the .NET Framework's ASP.NET Web API stuff which is often used as the API-side of a headless app that has an Angular app as a head that it could wear kinda like Princess Mombi in that 1980s "Return to Oz" movie. I had been under the false impression that Groovy compiled to Java, but instead they both compile to bytecode as does Scala. The bytecode may be run by the Java Virtual Machine or JVM. Gradle is a Groovy-based build system for Android, and Grails (Groovy on Rails) is a pimped out framework not unlike the Spring framework that allows one to do numerous things. I guess Spring is strictly Java and Grails strictly Groovy. It was pointed out to us that it's not too tough to get Java objects to be used in Groovy or vice versa. In both languages, objects inherit from java.lang.Object as the ultimate base much like good ol' object in C#. There is a joint compiler for Groovy and Java to allow for some crosstalk. Spock is a testing framework for Java and Groovy and the JDK is the Java Development Kit which has to be installed to install the JVM. SDKMAN! is package management for the Linux and Mac world. Groovy Beans DSL allows one to declare Java beans in the Spring framework. Groovy is statically typed but also very forgiving. You can get away with deferring a lot of sanity checks until runtime. IntelliJ or the IDE will warn you when you are going beyond your privileges, but Groovy will still likely let you go there. The def type is like any in TypeScript. Quartz is a job scheduler. Traits in Groovy allow for mixins. The BigDecimal type is probably the numeric type to use. It allows for floating point precision. As with ASP.NET MVC there is sort of a Grails equivalent of MVC with views (and certainly there is an MVC pattern separating concerns) which is sort of falling out of vogue and there is also a REST API thing. JBoss Application Server is a web server and JEE is Java Enterprise Edition also known as Java EE and formerly the Java 2 Platform and that is for distributed computing and other whistles and bells. JAR stands for Java Archive and JAR files are little deployable bits of code. They may be bundled into a bigger WAR file wherein WAR stands for Web Archive. There is a Goland ORM that has the name GORM, but it is the Grails' object relational mapping that is the GORM associated with Grails. It started out as a wrapper around Hibernate that allowed one to get out of writing HQL (Hibernate Query Language) with some of its tricks, but in modern times it has blossomed into much more. You may have interfaces for interacting with an object that do all mechanics based on naming convention (count in the name might be for getting a record count, etc.) as of version 6.1 and that too rides atop Hibernate, but there is also some new code for NoSQL solutions including MongoDB, Redis, Neo4J, Cassandra, and AxGorm. Micronaut is something like Grails coming for microservices and it will be released under the GNU general public license. A Sigmund Freud quote from one of Jack's slides was: "Analogies, it is true, decide nothing, but they can make one feel more at home."
Addendum 8/13/2018: JBoss is short for EJBoss which is short for Enterprise JavaBeans Open Source Software. Know your acronyms!
Is it really Instagram video that killed off Vine? So I've heard.
I took these two videos last night first at The Upstairs Lounge above Mekong and secondly at HandleBar in The Grove. The videos got cut off at the one minute mark which is going to seem superior to six seconds to a lot of people. I still personally miss Vine though.
(deleted)
I went to https://www.instagram.com/p/BgsbEBDg4Qy/?taken-by=jaeschke to embed the following and then clicked the three dots at the lower right to open up the option for: "Embed"
(deleted)
Addendum 12/9/2018: I have decided that I hate the two video clips above and that I am going to delete them. The video clip here is of "Sitarah" an opening act for G1M I saw two days ago. I will use this as an example instead.
View this post on Instagramis it Lauren Hill or Frankie Valli?
A post shared by Tom Jaeschke (@jaeschke) on
Friday, March 23, 2018
Make a wrapping component creating a double-headed snake of an Angular 4 Russian Doll hierarchy of components.
If component A wraps component B and that wraps component C and if in the template markup of component A you have the selector tab for component Z wrapping the selector tab of component B well in the markup for component Z you would need to have ng-content tags to make it make sense. But also in the template markup for component Z you could have the selector tag for component Y too!
The pipe 'async' could not be found
You need to add CommonModule at the "imports" metadata property of your module in your Angular 4 application to make this error go way. Also, import it like so:
import { CommonModule } from '@angular/common';
Use a double asterisk in Angular routing to make a catchall wildcard that will honor all possible routes.
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { MyComponent } from './my.component';
export const MyRoutes: Routes = [
{
path: '**',
component: MyComponent,
children: []
}
];
@NgModule({
imports: [
RouterModule.forChild(MyRoutes)
],
exports: [RouterModule]
})
export class MyModule {
}
Catchall made me think of catchall email addresses wherein you could sent to any random email address at a domain name back at the beginning of the millennium and it would route through to a particular email address for that domain name. These wildcards fell out of fashion. I remember Ted Hatfield of PrismNet explaining to me why these were bad yet I cannot recall the specific reason.
RangeError: Maximum call stack size exceeded
This error in Google Chrome Developer Tools just means that the browser (Google Chrome) cannot handle that many (X many) arguements. Something is running in a loop and bombarding the browser. I did contract work for Ben Huffman and his Huffman Computer Systems back in the 1990s and he famously opined "Don't pet a burning dog." which applies here.
Thursday, March 22, 2018
When you lose a menu bar or somehow otherwise change the layout in Visual Studio Code 1.17.2...
- Press the Alt key to make the File/Edit/Selection/View/Go/Debug/Tasks/Help menu appear if it is hidden.
- Go to: "View"
- Change the toggles for "Toggle Full Screen" and "Toggle Zen Mode" and "Toggle Menu Bar" as applicable.
Addendum 5/1/2018: It was pointed out to me today that F11 does the trick too.
Addendum 7/17/2019: In version 1.36.1, and likely starting a some point earlier, the toggles are nested in an "Appearance" submenu beneath the "View" menu.
Bewilderment and Bemusement
That must have been what this girl was feeling when I asked to take her picture and I suspect it is what Vladimir Putin and his government are thinking in watching America's free society. They shouldn't smirk. We (Americans) actually have an economy bigger than that of Mexico and it isn't one-dimensionally based on oil and a lot of that is due to the fact that people actually want to live here, but not to rant about how real capitalism is better than the late-to-capitalism stuff... The Russians who "meddled" in our presidential election are probably amused that they could do so exploiting what are really just loopholes in free speech. Pump advertisements onto Facebook to influence people. Target specific segments to make a difference in flipping what was blue to what could be red, etc. But having said all that the Russian meddling really didn't do anything wrong. It is all free speech after all. I guess someone did hack Hillary Clinton's campaign and find out how much she was being paid for speeches and that Donna Brazile of CNN leaked questions for an upcoming debate to Hillary (that ended up on WikiLeaks), but aren't you glad you know those things instead of them being kept a secret? I voted for Hillary in 2016 and I even voted for Hillary over Bernie Sanders in her pregame power struggle with him preferring in both cases boring to crazy, but I sense a minor trend in U.S. presidential elections in which the more interesting candidate ends up beating the less interesting candidate. You have to go all the way back to 1988 when the first president Bush faced off against Michael Dukakis for my model to break. It is hard to say which one of those men was more boring, but I guess I give Dukakis the edge in being more interesting in that at least he had big eyebrows. Anyhow, following the pattern, Donald Trump with a history of saying racist things and a wink at torture went to The White House and a lot of liberals are looking for an explanation. Enter the Russian meddling. For all of the crybaby crying that Hillary has done since she lost I have never heard her point to the social media stuff or the hack that revealed some embarrassing secrets of hers as the reason for her loss. Instead she blames James Comey's handling of her email scandal and it is the talking heads on the left who instead trumpet the Russian meddling stuff. Hillary won't go there herself because she knows there is little to it. I have to believe that the meddling didn't move the needle more than a half of a percentage point in the polls at best, and again a lot of the targeted marketing stuff is just free speech and the stuff leaked from a hack of Hillary is stuff we should have been told anyways. More recently it has been found out that Facebook gave data to an academic agency that then turned around and fed it to the Trump campaign allowing the campaign itself to do some targeting marking. Hey, and what if Trump was colluding with the Russians in the marketing and hacking? How awful? Not really. Again, I don't think the needle moved more than a half of a percentage point, and if I'm wrong, if we as Americans can be so easily manipulated, well then yes there is a reason for outsiders to laugh at our openness. I don't think however the needle moved much. This touches on how hard it is to flip someone's political opinion on social media in spite of how easy it might be to figure out what their opinions are based on their Facebook likes. This makes me smirk at all the ruckus. I guess it's just politics. When Hillary's husband was president his enemies tried to make a big deal out of Monica Lewinsky to destroy him and that was silly too. The girl in the photo is another encounter from the Mardi Gras event mentioned here and here.
Wednesday, March 21, 2018
What does SimpleChanges at ngOnChanges do anyways?
Following up on this, this has the following example of inspecting specifically what changed at ngOnChanges with SimpleChanges:
ngOnChanges(changes: SimpleChanges) {
for (let propName in changes) {
let change = changes[propName];
let curVal = JSON.stringify(change.currentValue);
let prevVal = JSON.stringify(change.previousValue);
console.log(curVal);
console.log(prevVal);
}
}
The title tooltip is not showing up at a button when the button is disabled?
Slap this CSS on the button to fix the problem:
pointer-events: auto;
Tuesday, March 20, 2018
git reset --hard HEAD~1
As a Git Bash command, this is going to throw away the most recent commit to your branch. (Using "soft " instead of "hard" will unwind the changes while destroying the commit to your branch. The uncommitted changes will be back at your source code however instead of being reverted.)
a good pattern for barrels
A good pattern for barrel files in an Angular 4 app is to make an index.ts file be an index of what is in the folder it sits in and not an index of what imports the files in the folder have in common. Do not try to use an index at a folder to clean up what is in that particular folder. Instead let it represent the folder when files and different folders call out to things in that folder. When referencing an index file in another folder, you make make an import devoid of the actual index name/word such that...
import * as Whatever from '../../yin/yang/index';
...may be be simplified as...
import * as Whatever from '../../yin/yang';
Addendum 3/21/2018: The as variable should probably be in camel case and not Pascal case and thus be whatever and not Whatever.
I've decided that the funny pocket on the side of the laptop bag which my work gave me must be for holding an umbrella.
You can't put anything in the pocket as it is open on both ends and smaller things would just fall out. Maybe this fat strap just holds an umbrella against the bag with tension? That seems to work. Today's initial trial of my theory was a success. Well, it only works if the laptop is in the bag making it fat. It will not work when the bag is empty and flimsy. I mostly do not move the bag when the bag is without the laptop so this is fine for walking to and from my car for example.
Monday, March 19, 2018
Use the export keyword when creating a barrel file in an Angular 4 app.
This is a distinction to what I mention here. If we have whatever.ts that starts out like so...
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
...then perhaps an index.ts file would look like so in the name of abstracting this stuff out:
export { Routes, RouterModule } from '@angular/router';
export { NgModule } from '@angular/core';
That would then be looped in back at whatever.ts like so:
import { Routes, RouterModule, NgModule } from './index';
You could also do this...
import * as Whatever from './index';
But that means you would have to call out to RouterModule as Whatever.RouterModule instead of just RouterModule.
Sunday, March 18, 2018
escaping let i=index in *ngFor loops
I find myself writing stuff like this all the time:
<div *ngFor="let mouse of mice; let i=index" ...
Inside the loop I would then hand i on as a variable to a method when a button is clicked or something. My superior is not in love with the i and prefers if possible that there be a convenience method to call on the type of which there is a collection of that type which is being looped through. So if mice where an Array<Mouse> then instead of having a button (click) event call doWhatever(i); there would instead be a .doWhatever() hanging off of mouse which would do the same thing. This may not always be possible, but think about it.
Saturday, March 17, 2018
save off a .jpg_large image from Twitter?
When you try to save off https://pbs.twimg.com/media/DPQm5d5U8AA8-Tt.jpg:large and you are asked where you want to save DPQm5d5U8AA8-Tt.jpg_large because somehow the colon became an underscore, just remember that you will need to rename the file to DPQm5d5U8AA8-Tt.jpg as there is no .jpg_large format.
Paginated list of records in Angular Materials?
https://material.angular.io/components/table/overview might just be what we are looking for. A solution has been missing from the Angular space from a while, and only with Angular 5 and up do we get Angular Materials and the CDK. Of course, I have not used this yet myself as I am still working with Angular 4 professionally. Two jobs ago I worked on the challenge of just making my own thing instead. I was trying to remember what I did in attempting articulating it over text messaging today to a friend. Here is what I sent complete with bad grammar:
I just made something that expected a type I wrote. Off of the custom type, GridDetails, or whatever was a getsetter for an Array<any> which would be the collection for actual records. Maybe you could hand this in at the constructor. Anyways the GridDetails object would have other getsetter for number of pages in pagination and the grid had to be smart enough to compensate with a default if you left a setting off. To make a rightmost column full of buttons there would a Boolean for whether or not to show the column and a getsetter that expected a function that took a number and returned void. The number was for the index and the function itself could do a redirect or something.
Friday, March 16, 2018
opacity in cascading style sheets
This, in CSS, makes something halfway opaque:
#something {
opacity: 0.5;
}
Why is Sass better than LESS?
This suggests that Sass has a two-thirds share of its space in terms of adoption, killing all competition! Why so? What makes it better? This offers that in hardcore mixin mechanics like if/else logic and looping that Sass shines. Meh. Who cares? Are you really going to write your own Bootstrap? You would probably just use Bootstrap or write something less one-size-fits-all which does not demand a bunch of conditional logic. If you are working on a project with LESS that is proably just fine. That said, if you are spinning up something new you might as well make the decision to go with Sass as you are making it possible to get crazy if you really had to even though you probably won't.
Delete a video clip at YouTube.
- Log in as you.
- Go to the https://www.youtube.com URL for the video clip, or really go to any of your video clips.
- Click the "EDIT VIDEO" button at the lower right of the video itself.
- Click "VIDEO MANAGER" at the upper left.
- You will see a list of your videos each with "Edit" next to them and a down arrow by "Edit" which should be clicked to reveal the "Delete" option.
- Delete as need be.
Addendum 12/8/2018: I don't know if what is above is any good anymore. I think you should log in as you, go to your video clips (maybe with the "My Channel" option from the dropdown menu that comes out of your avatar at the upper right), click on the video clip in question, and then the "EDIT VIDEO" button at its lower right. Finally, there is an icon that looks like three dots in a vertical line at the upper left. There is an option for "Delete" inside of the "Options" menu that folds out of this thing.
Change the privacy of a video clip at YouTube.
- Log in as you.
- Go to the https://www.youtube.com URL for the video clip.
- Click the "EDIT VIDEO" button at the lower right of the video itself.
- At the lower right of the pane of controls that appears there will be a drop down menu which is unlabeled but contains: Public, Unlisted, and Private
- Make a change and then press the "Save changes" button at the far lower right.
Thursday, March 15, 2018
Watch at GitHub's web interface!
If you log into the web interface and go to a project at the top right you will see Watch, Star, and Fork, and herein you may click "Watch" to pick the option for "Watching" and this will give you all sorts of email spam about changes to the project. (Maybe I should embrace this now that I live in the "Show Me" state, eh?) This should alert you when your pull requests are conflicted.
I finally have learned how to make an else work with an *ngIf in Angular 4.
It turns out that it involes a template. This eluded me for some time.
Status:
<ol>
<li>awake</li>
<li *ngIf="isWithPlan else noPlan">ready</li>
<ng-template #noPlan>
<li>unsure</li>
</ng-template>
</ol>
Wednesday, March 14, 2018
window.location.href and console.log are not friends in JavaScript
Do not expect to redirect elsewhere while writing to the console immediate beforehand. The redirect will still happen but you'll see nothing at the console unless it happens in another blob of code that is asynchronously referred to.
error: cannot pull with rebase: Your index contains uncommitted changes.
You need to commit at your branch at Git Bash's command line before you may switch to master and then rebase changes in. That will make this error go away.
.reduce in JavaScript
This allows one to run a function against an array and this has this example:
const euros = [29.76, 41.85, 46.5];
const sum = euros.reduce((total, amount) => total + amount);
...and sum ends up with 118.11 in it in this example. The first two variables (named "total" and "amount" here) seem to represent first some fashion of grow-over-time-state-stash that gets returned at the end (starting with the item at position zero and warping over time with every other position) and second the immediately value out of the array when looping through it. The looping runs one less time than there are items in the collection! The link I give here suggests "index" and "array" are potential 3rd and 4th variables. The 4th is the whole of the array and the 3rd is the current position you are looping through. Again, this starts at one and not zero.
Make copy spin with CSS alone!
This just makes a spinning green X!
<!DOCTYPE html>
<html>
<head>
<title>Whatever</title>
</head>
<style>
#actor {
color: #00FF00;
}
#actor:before {
-webkit-animation-name: spin;
-webkit-animation-duration: 1250ms;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-name: spin;
-moz-animation-duration: 1250ms;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
-ms-animation-name: spin;
-ms-animation-duration: 1250ms;
-ms-animation-iteration-count: infinite;
-ms-animation-timing-function: linear;
animation-name: spin;
animation-duration: 1250ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
display:inline-block;
content: "X";
}
@-webkit-keyframes spin {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
@-moz-keyframes spin {
from { -moz-transform: rotate(0deg); }
to { -moz-transform: rotate(360deg); }
}
@-ms-keyframes spin {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
from {transform:rotate(0deg);}
to {transform:rotate(360deg);}
}
#outside {
padding: 40px;
}
</style>
<body>
<div id="outside">
<div id="actor"></div>
</div>
</body>
</html>
TypeError: Cannot read property 'length' of undefined
To fix this just restart the server... stop it and rerun: npm start (at the very least you'll get past the vague error to a real error) One of the ways in which Angular 2 up is so much better than Angular 1 is the friendlier error messages. This error is the one bad, cryptic message.
git rebase --skip
This should be used if you are in step 3 of 4 of a rebase and you cannot commit because it appears you are caught up. This command, at a Git Bash shell, should let you go on to the next rebase. I realized just today that the Atlassian Bitbucket magic for aggregating commits does not exist in the Git Bash space and the longer an outstanding pull request lingers unmerged the more rebasing you will have to do against it to accommodate all of the other pull requests that were merged before yours. Once again, I am in an environment where the tooling gets in the way of checking in early and often. It's infuriating. It's seeming really stupid and backwards now that I know the grass is greener on the other side of the fence too. I know the answer to the "Do you see yourself as having any weaknesses?" interview question.
git config --system core.longpaths true
This Git Bash command should up the allowable length of a path to a file to 4096 characters up from 260 characters per this. If you get a permissions error, try this instead:
git config core.longpaths true
Tuesday, March 13, 2018
Store in NgRx and Angular 4?
Sometimes things will come back from a selector in a Store<Array<Whatever>> shape instead of an Observable<Array<Whatever>> shape even though Store is an Observable and you may still subscribe to it to pull stuff out of it. There is also a Subject instead of Store or Observable which I don't understand yet. Specifically, for Store you will need an import like so:
import { Store } from '@ngrx/store';
I don't yet understand what bonus magic comes with Store.
more on ViewEncapsulation
Following up on what I elude to here, this has this example:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
This should allow one to have a cascading effect from outer component to inner component that one normally associates with ::ng-deep without ::ng-deep assuming you have ViewEncapsulation.None at the inner component. You will need an import like so:
import { ViewEncapsulation } from '@angular/core';
If you don't need a cascading effect, if you just need to use the outer component's stylesheet at the inner component, you could always just import the outer component's stylesheet at styleUrls as seen above alongside ./app.component.css as that would work too. Don't want to import all of the styles? Break the outer component's stylesheet in two!
Don't put your own code in the constructor of an "Action" implementing Action in model.d.ts of @ngrx/store as it will never run.
Clearly public variables may be looped in inside of the parenthesis at the constructor but you can't log something to the console inside of the curly braces. This is the painful lesson for the day. (This all has to do with using Redux in Angular.)
Monday, March 12, 2018
I think I have a new favorite restaurant.
As much as I eat at Olive Garden I am nonetheless smart enough to know it's not cool to list that as my favorite restaurant. A favorite restaurant should be a one of a kind place or at least of a small, regional chain. I think Tazé Mediterranean Street Food is my new favorite. I ate there with coworkers for the first time today. This is a one-of-a-kind family-run place and it is Mediterranean food. I think this is the first Mediterranean place I've been that has a Freebirds/Chipotle walk-down-an-assembly-line and then pay at a register thing going on. It's like those customize-your-own-burrito places only you customize a gyro instead of a burrito. I built out a gyro today and got jalapeño hummus and couscous as my sides as seen here. The meal was da bomb. I will definitely be back. Soco's Gyros near where I live is OK, but it is more of what you'd expect from a traditional Mediterranean restaurant (with the exception of the religious music playing) and does not have customizability of what I discovered today, so will probably never go back there even though it is within a mile of my apartment in the Concord neighborhood and today's find is in the heart of St. Louis. What is more, today's meal was just better. The customizability will probably just give way to me having the same thing every visit knowing how I am. Tazé Mediterranean Street Food is in the part of St. Louis that does not sit in St. Louis County. This might be thought of as the heart of the city. St. Louis is one of a handful of what are thought of as independent cities in the United States of America which almost unbelievably do not sit in a county. There is a St. Louis County wrapping St. Louis on all sides except the side pressed against the Mississippi River to the East in sort of a C shape, and I am a little fuzzy on whether or not if someone can be in St. Louis County and also St. Louis. An Uber driver told me that St. Louis County is referred to as "The County" but in my case, as I have a 63128 zip code, that I am still in what might be thought of as "The City" even though I am not in the independent part of the city. Certainly, I have a St. Louis street address and not a Concord street address. Chesterfield, MO might be an example of a city in "The County" that is a city other than St. Louis. It's all a bit fuzzy. Soco's Gyros would be short for South County's Gyros (I live on the South side of the C shape) and thus that kinda says "The County" and not "The City" so... whatever. Arnold, MO a little South of me sort of is to St. Louis what Round Rock is to Austin and Jefferson County where it sits, bordering South County to the South, is sort of the Williamson County of my immediate environment. I digress again! Up until now I think I would have given Athenian Bar & Grill in Austin, Texas as my favorite restaurant if asked. The food is also Mediterranean there too. The place is run by a husband and wife team from Albania, an Anil and Gladys Simicia. Gladys' name is pronounced "Lattice" and she would always greet me with "Hello my friend!" alongside a smile and thick Albanian accent. The photo of her here is from 10/21/2015.
Addendum 3/14/2018: I have learned there is a second location for Tazé Mediterranean Street Food upon a second visit today. It's at 8½ South Euclid, St. Louis, MO 63108 while 626 Washington Ave #103, St. Louis, MO 63101 is the original that I have visited twice now. It has been around for a couple of years and the new one for less than a year.
You don't have to assign a property of the same name to the property you wish to overpower when doctoring objects with the spread operator in TypeScript.
let foo = {
bar: 13,
baz: 42,
qux: 69
};
let qux = 86;
foo = {
...foo,
qux: qux
}
console.log(foo);
What is above and what is below do the same thing.
let foo = {
bar: 13,
baz: 42,
qux: 69
};
let qux = 86;
foo = {
...foo,
qux
}
console.log(foo);
mixing arrays and objects with the spread operator in TypeScript
let x = [13, 42, 69, 86];
let y = {
foo: 13,
bar: 42,
baz: 69,
qux: 86,
};
let z = {
...x,
...y
};
console.log(z);
...creates an object like this:
{
0: 13,
1: 42,
2: 69,
3: 86,
bar: 42,
baz: 69,
foo: 13,
qux: 86
}
While...
let x = [13, 42, 69, 86];
let y = {
foo: 13,
bar: 42,
baz: 69,
qux: 86,
};
let z = [
...x,
...y
];
console.log(z);
...has a squiggly red line for "I can't compile" at the TypeScript Playground, but also returns an array like this...
[13, 42, 69, 86, {foo: 13, bar: 42, baz: 69, qux: 86}]
Saturday, March 10, 2018
optional workaround
In TypeScript adding a ? at the end of a parameter makes it optional. We see this in interfaces a lot right? Did you know that you may have it in function signatures too? This will let you get away with providing one less variable if imposed at one variable there. In JavaScript if you have a function with four variables at the signature and you only specify two when calling the function the ungiven items end up as variables which are undefined in JavaScript terms. Unfortunately, the one way in which I have found in which TypeScript is not a superset of JavaScript is that you cannot do such a trick in TypeScript as the compiler will complain. You may hack around the shortcoming with the question mark, but obviously that doesn't cure the is-not-a-superset problem, eh?
I'm an Olympic Athlete?
Forest Park in St. Louis is supposedly as big or bigger than Central Park in New York! I went for the first time today in hopes of finding someone I could manipulate into taking some photos of me. My victim turned out to be a woman parking next to me who asked me where the meter was. I told her that I used the Parkmobile app, was of no help to her, and then talked her into being my cameraman. Awesome. These are some of the photos she took of me pretending to be a certain someone, Thomas Jaeschke. A coworker once asked me if I hate having to now share my name with him as if I were Michael Bolton in Office Space, and no I do not. All and all, what's not to like about the other Tom Jaeschke? Every time you see a picture of him he's just so happy to be playing volleyball as if nothing in the world could be more important or, alternatively, as if nothing in the world is important and thus: yay for volleyball! Even though I had an exclusive lock on the name Tom Jaeschke at Google up until maybe 2013 when he showed up and took my name away from me, I will not refer to him as a no talent ass clown. I sense someone just as silly and goofy as yours truly and thus I cannot judge harshly. What do you think of my attempt to channel him? Do I pull off looking nineteen years younger (consistent with my actual maturity) and eight inches taller? It's kinda flimsy, huh? I guess it might help if I wasn't holding a volleyball for my first time today since the P.E. class in my sophomore year in high school. I wasn't too shabby at volleyball in that P.E. class. I was the kid who got picked last for everything else, but I remember that Kevin Tree Breeze E (last name phonetically represented and sorry for no photographic memory) pulled me in to be his partner in some two versus two shit once. I can think of another time with two full teams facing off in my freshman year when the ball bounced off one of our guys and flew out of bounds on our side of the net and I ran twenty feet beyond borders and was able to save it heroically and lob it back to the other side in a miracle move. In that circumstance however I think there was some more back and forth and then the enemy just scored against our team anyways so I was flashy for naught. Times I screwed up at volleyball included trying to serve with an underhanded lob by way of a bounce off the fist while I didn't tuck my thumb into my fist causing the ball to go in the wrong direction. Man I hated high school. I try to never think of it. I suppose I'm only thinking of it now because I am thinking of volleyball for the first time in a quarter century. The other me clearly couldn't get enough of volleyball in high school and went all the way to the Olympics with it. When I was at Veteran's Affairs, Keith Jaeger the DBA with Kforce had a daughter who went to the junior Olympics and helped USA win the gold. Supposedly she had a revolutionary way of firing the volleyball across the net kinda like a serve in tennis. She played tennis before picking up volleyball I think. Maybe her name was Sarah. Again, no photographic memory. Enough already. My cosplay is complete.
Friday, March 9, 2018
Debug inside of a Node process with Visual Studio Code 1.17.2.
- Open the appropriate folder in Visual Studio Code.
- At the vertical row of five icons at the upper left for Explorer, Search, Source Control, Debug, and Extensions click on: Debug
- Click on the gear icon with a red dot at its upper right (or there may not be a red dot too) at the top nav to create a launch.json file.
- Change the path in the launch.json file to the .js file you would normally run by name by just preceding it's name with "node" and a space at a Windows 7 command prompt.
- Put debugger; as a line of code in your code base.
- Click the green go arrow up by the gear icon to debug and see if you can stop at your debugger; line.
Thursday, March 8, 2018
no one likes my naming
I have gotten plenty of criticism over my variable names. I have tried to be explicit which reads to others as overly verbose. Just today I was told that variable names should be terse but understandable. I am failing at the terse part. I do not have a methodology for approaching terse but understandable. Maybe every verbose name just needs a trim down in a second step. I hate this because I feel like the trim down is a dumb down and that feels insincere.
git stash apply
As a Git Bash command will try to pull back out of stash the last thing you put in after you change branches and...
git reset --hard
...will undo at a branch the changes you should not have made there to begin with.
ghetto hack to make a command-prompt-run Node process in Windows 7 just hang out for five seconds in the name of testing a race condition
setTimeout did not want to work for me for some reason so...
console.log('timer is starting');
var counter = 0;
while (counter < 100000) {
console.log(counter);
counter++;
}
console.log('five seconds have passed');
find an item in a collection within a collection with a .some inside a .some
let id = 7;
let match = null;
let foo = {
bar: [
{
baz: [
{
qux: 1,
color: "red"
},
{
qux: 2,
color: "green"
},
{
qux: 3,
color: "blue"
}
]
},
{
baz: [
{
qux: 4,
color: "cyan"
},
{
qux: 5,
color: "magenta"
},
{
qux: 6,
color: "yellow"
},
{
qux: 7,
color: "black"
}
]
},
{
baz: [
{
qux: 8,
color: "plaid"
},
{
qux: 9,
color: "paisley"
}
]
}
]
}
foo.bar.some(x => x.baz.some(y => {
if (y.qux === id) {
match = y;
return true;
}
return false;
}));
alert(match.qux + " - " + match.color);
.map in JavaScript does not mutate state when introducing changes the way a .forEach does.
Instead, you will get a brand new array with brand new records. The pointers to the old array and old records will not be maintained.
Make a moment-in-time-specific string for a timestamping in JavaScript.
var foo = new Date().getTime().toString();
In the Redux tab that the Redux plugin for Google Chrome makes at Google Chrome Developer Tools, the "State" tab should show you what is in your store.
The "Diff" tab should show you what has changed. I think.
ComponentFactoryResolver
...is the magic to spin up a component dynamically in code in an Angular 4 app in lieu of by way of a selector tag or that which is bootstrapped in a module at the bootstrap metadata property. In your module amongst the metadata properties like "bootstrap" and "providers" is "entryComponents" and herein you will need to reference the dynamic component as you will also need to at "declarations" as well. I don't really understand ComponentFactoryResolver just yet.
Write tests as you go?
This is great if you can. Ideally if you have all the pieces of your puzzle laid out and you've whiteboarded the sequence diagram this should be feasible and good policy moreover. In my experience I am usually struggling to figure something out as I code leading to an impracticality for test-as-you-go. I had a conversation with a coworker over lunch about this a few days back and just yesterday we paired on something we didn't understand fully from the outside looking in and the thing I am thinking of just did not lend itself to test-as-you-go. Abstractly you could do all the fact-finding and then turn around and do some whiteboarding, but by the time you've proved out the fact-finding you already have a lot of code written. In a tech a talk I can't fully remember I recall a speaker suggesting that you should really test as you go as if you just plan to write the tests at the end of your work you will find yourself with surprising frequency in challenges in which you work up to a deadline, barely get something done, and then skip the tests. That is kinda my experience too. I can think of jobs I had which fit with as much and as much basically leads to sparse testing that does not allow for the safeguard one needs to make sweeping changes. It becomes easy to break stuff when refactoring and thus there is a reliance on a testing team that TDD purists are able to escape somehow. So is sparse testing, testing only the really core logic or testing here and there, worth doing at all? Is it like doing Scrum (not LSD, i.e. Lean Software Development) with point estimates and Fibonacci cards without any burndown chart to make the calculated velocity matter or screwing up an estimate have consequences? No. It is still worth doing. Every developer should intermittently write tests if they can't do it consistently. With testable code comes good code, and specifically I mean dependency injection. I am the rare developer who has never written any C++ but I am hip to what goes on therein in procedural messes with dependencies reached out to midstream in lieu of being handed in in an OOP (object-oriented programming) manner. I've heard the stories let's say. In contrast, in the environments where I've done C# with minimal testing StructureMap is the norm and everything that we write that we don't test is something that we could test. The separation of concerns associated with the S of the SOLID principals is pronounced. The exercise of architecting something that is going to have a few tests in its Hello World phase to begin with is hence a really smart move.
I saw Captain SpaceTime perform at The Crack Fox today.
And, by today I mean at one in the morning just inside today. He was pretty good. I tried to find some of his music online afterwards, but all I could find was this Facebook page. It looks like he used to be a three man group called Captain SpaceTime. Without knowing what happened I like to imagine that the other two guys bailed on the frontman leaving the frontman to do it solo and the identity of the band bent across space/time to become the identity of the individual. Kinda like how Save Ferris decayed into just Monique Powell only she doesn't call herself Save Ferris. Bad comparison?
The white spot amid all the black in the bottom center of the photo is more of the problem shown off in the last photo of Amber Lindholm here. It's probably time for me to get away from my six year old iPhone 4S. I keep procrastinating.
Wednesday, March 7, 2018
Avoid newing up classes in a mapping operation in TypeScript in the name of making code less verbose.
This...
saveStuff(): void {
this.felines = this.cats.map((cat: Cat) => {
let feline = new Feline();
feline.Id = cat.Collar.Tag.SerialNumber;
feline.Name = cat.Name;
feline.NumberOfLives = cat.LivesRemaining;
return feline;
});
}
...could be cleaned up like so:
saveStuff(): void {
this.felines = this.cats.map((cat: Cat) => ({
Id: cat.Collar.Tag.SerialNumber,
Name: cat.Name,
NumberOfLives: cat.LivesRemaining
}));
}
Depending on you, you may want a type assertion tossed in too.
saveStuff(): void {
this.felines = this.cats.map((cat: Cat) => (<Feline>{
Id: cat.Collar.Tag.SerialNumber,
Name: cat.Name,
NumberOfLives: cat.LivesRemaining
}));
}
This is legitimate too which surprised me.
saveStuff(): void {
this.felines = this.cats.map((cat: Cat) => <Feline>({
Id: cat.Collar.Tag.SerialNumber,
Name: cat.Name,
NumberOfLives: cat.LivesRemaining
}));
}
Even this will compile and assert (twice over) but I don't recommend it...
saveStuff(): void {
this.felines = this.cats.map((cat: Cat) => <Feline>(<Feline>{
Id: cat.Collar.Tag.SerialNumber,
Name: cat.Name,
NumberOfLives: cat.LivesRemaining
}));
}
how to create a story in Jira's interface of the moment, March 7th of 2018
- Click the "Create" button at the top nav. It should be there no matter where you are.
- A modal will appear. You may need to set "Issue Type" to explicitly be Story instead of Bug, Task or Epic. Fill out the fields as best as you can* and then click the "Create" button at the bottom of the modal.
- Click on the "Issues" icon at the left. It looks like a magnifying glass by some horizontal lines. It should take you to a list of open issues and hopefully you'll see the thing you just created there.
*The "Reporter" field is going to advertise you as the reporter, the creator. There does not seem to be a way to reassign this field.
A high order function in JavaScript is a function that returns a function.
...like a closure, only not necessarily enclosing state. I guess every closure is a high order function but not every high order function is a closure.
git remote -v
...gives you some details at a Git Bash shell for where you are pulling source code from. Where did you clone from to begin with? ...etc.
Tuesday, March 6, 2018
Extra date stamp fields at a spool of unsaved items?
This might be wise. Whenever someone clicks the save button and the unsaved things are sent to an API endpoint that person could then make a change to add a new unsaved item to the array before the API callback returns and drops everything out of the array. Maybe it is best if the process after the API call does not drop everything out of the array at the end of the promise returning as that could cost one some unsaved changes back at whatever means is being used to store a state stash at the UI. Instead at this point, the point of the promise returning, what was sent could be cross-compared to what is at the master records of unsaved changes and only items with the same timestamp could be discarded.
NVL in Oracle's SQL allows you to substitute a value if the main value in null.
This has this example:
SELECT NVL(supplier_city, 'n/a')
FROM suppliers;
Put an extension such as Augury or Redux DevTools into Google Chrome from an unzipped folder full of files as a plugin.
- go to chrome://extensions/ at the Google Chrome browser
- click the "Load unpacked extension..." button
- browse to the applicable folder
:host input[type=number] {
Here the :host is for global CSS in an Angular 4 stylesheet, bridging all components.
Doctor-up collections in a reducer of Redux in an Angular 4 application without mutating state by dropping and recreating collections.
Below we are altering only the answers in the collection of answers that have changes and we are not adding items to unsavedAnswers that are already in the collection as we don't want dupes.
case PLAN.UPDATE_ANSWERS:
const updateAnswerAction = <UpdateAnswersAction>action;
return {
...state,
answers: state.answers.map((answer: PlanAnswerModel) => {
const match = (updateAnswerAction.model.find(q => q.question.id ===
answer.questionId));
return (match) ? {
...answer,
value: match.answer,
skipped: match.skipped
}
: answer;
}),
unsavedAnswers: [
...state.unsavedAnswers.filter(x => !updateAnswerAction.model.some(y =>
y.question.id === x.question.id)),
...updateAnswerAction.model
]
};
default:
return state;
}
}
Turn off the infuriating ability to drag folders into other folders accidentally at the Explorer in Visual Studio Code 1.17.2.
- go to: File > Preferences > Settings
- add to the JSON object that appears a line reading:
,"explorer.enableDragAndDrop": false
This is the same place one would set the amount of spaces in tabs also, but do not set that setting. Leave it be at four spaces. Per this the way to do that might be...
",editor.tabSize": 4
,"editor.insertSpaces": true
,"editor.insertSpaces": true
When you use an .subscribe with an Observable in an Angular 4 component you should explictly destroy it.
I won't show the whole of the component, but let's assume that there are import statements. Let's include this one:
import { ISubscription } from 'rxjs/Subscription'
As public properties on the component itself, let's have:
unsavedAnswers: Observable<Array<SaveAnswerEventModel>>;
unsavedAnswersState: Array<SaveAnswerEventModel>;
unsavedAnswersSubscription: ISubscription;
Let's use a selector as suggested here to populate these as follows. Note the .subscribe please.
ngOnInit() {
this.unsavedAnswers = this.store.select(getUnsavedAnswers);
this.unsavedAnswersSubscription = this.unsavedAnswers.subscribe(result =>
this.unsavedAnswersState = result);
}
When the component dies, so too should the .subscribe die. Don't let it hang out to create a memory leak.
ngOnDestroy(){
this.unsavedAnswersSubscription.unsubscribe();
}
We might actually use unsavedAnswersState at a button click event like this:
saveUnsavedAnswers(): void {
console.log(this.unsavedAnswersState);
let answers = this.unsavedAnswersState.map((model: SaveAnswerEventModel) => {
let saveAnswerModel = new SaveAnswerModel();
saveAnswerModel.questionId = model.question.id;
saveAnswerModel.answer = model.answer;
saveAnswerModel.skipped = model.skipped;
return saveAnswerModel;
});
this.store.dispatch(new SaveAnswersRequestAction(answers));
}
This is an example of a scenario wherein you have to use a .subscribe in TypeScript itself in lieu of just using the async pipe in a template which both does the same thing and cleans itself up without you explicitly having to do so. Beware of the potential for a performance hit with this stuff. It's going to feel good until you start eating yourself.
.take(1) and .first() in Observable mechanics
A selector is going to have something like this in it, and not just this. There will be other import statements too.
import { createSelector } from '@ngrx/store';
export const getBase = function (state: DataContext) {
return state && state.base ? state.base : new BaseModel();
};
export const getStuff = createSelector(
getBase,
(x: BaseModel) => {
return x.Whatever;
}
);
\node_modules\@ngrx\store\src\selector.d.ts is where one will find the createSelector function. Anyhow, an example of using .take(1) with this stuff would be:
return this.store.select(getStuff).take(1);
This suggests that you may chain other things like a .subscribe off of a .first() which could be used in lieu of .take(1) and then catch an error. Obviously the advantage with .take is you could take more than the first item. You cannot chain beyond it however.
Monday, March 5, 2018
get at the key code stuff in an Angular 4 app
This, or perhaps a keydown event, goes in the template on an input control...
(keyup)="getKeyCode($event)"
And on the TypeScript side of a component...
getKeyCode(event:any):void {
alert(event.keyCode);
}
The webpage at chrome://plugins/ might be temporarily down or it may have moved permanently to a new web address.
chrome://plugins has been replaced with chrome://settings/content
Turn off Flash at the browser!
At chrome://settings/content go to Flash and turn it off in Google Chrome. In IE, go to "Manage add-ons" at the gear and then find Flash under: Toolbars and Extensions (you may need to refresh the browser)
When searching with Ctrl-Shift-F in Visual Studio Code 1.17.2, the search box will not react as you type.
Instead the search results change when you press Enter. This takes some getting used to.
When you accidentally rotate the screen on its side in Windows 10...
Click in the desktop and then press: Ctrl-Alt-Up Arrow
Sunday, March 4, 2018
.some in JavaScript
Alright, this has this example:
var array = [1, 2, 3, 4, 5];
var even = function(element) {
return element % 2 === 0;
};
console.log(array.some(even));
What is above will spit true out to the console. I guess if there is one match of the condition it will return true and otherwise it will return false. What is more, and a little different, I was able to refactor the following TypeScript...
let matchedModel: SaveAnswerEventModel = null;
updateAnswerAction.model.forEach((saveAnswerEventModel) => {
if (saveAnswerEventModel.question.id === answer.questionId) {
matchedModel = saveAnswerEventModel;
}
});
...into this:
let matchedModel: SaveAnswerEventModel = null;
updateAnswerAction.model.some((saveAnswerEventModel) => {
if (saveAnswerEventModel.question.id === answer.questionId) {
matchedModel = saveAnswerEventModel;
}
return true;
});
...is this a little less expensive? Does .some just fall out of looping when it finds a match? I don't know. In the last of the code snippets above we have to return true or false. We cannot return a more complicated type.
Saturday, March 3, 2018
no more Flash?
A little bird tells me that Adobe will stop supporting Flash in 2020 and that means browsers coming out afterwards will stop supporting it just as they stopped supporting the blink tag. Now how am I going to play Russian Roulette without Flash?
Look at the weird HTML tags for this stuff. I had completely forgotten about all this.
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/
swflash.cab#version=6,0,29,0" type="application/x-shockwave-flash" width="750"
height="600" base="games">
<param name="movie" value="https://file.gamesodo.com/swf/game_8756.swf">
<param name="quality" value="high">
<param name="menu" value="false">
<embed src="https://file.gamesodo.com/swf/game_8756.swf" quality="high"
pluginspage="https://www.macromedia.com/go/getflashplayer/"
type="application/x-shockwave-flash" menu="false" width="750" height="600"
base="games">
</object>
Friday, March 2, 2018
.includes off of an array
It does what you'd expect in JavaScript and this has this example:
var array1 = [1, 2, 3];
console.log(array1.includes(2));
var pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
console.log(pets.includes('at'));
This is going to log to the console:
- true
- true
- false
Thursday, March 1, 2018
I saw Jeff St. Germain and Kevin Grossnicklaus speak on making Angular 5 applications secure at the STL Angular Meetup at Bullhorn last night.
OpenID Connect is a protocol for tokens on top of OAuth 2.0 which allows for identification and authorization from a client elsewhere (a JavaScript app that cannot be secured in and of itself as all code just lives at the browser) that is sometimes abbreviated at just: oidc ...Jeff (seated) and Kevin (standing) use a technology called Identity Server (specifically Identity Server 4) to empower such identity management in lieu of using other openesque, out-in-the-world technologies such as the login for Facebook, Twitter, or gmail to do as much. (With the other three one creates an app at their store and then logs in against it.) JetBrains Rider is a cross-platform IDE that one may use for .NET and C# too and Jeff and Kevin use it to edit C# at their Identity Server implementation and work on Macintoshes. Yes, Identity Server is of .NET Core! It is free open source software and there is a GitHub project for it somewhere, and, you guessed it, it uses oidc too. Specifically, it passes JWT (pronounced "Jot") tokens from the client to an API server to Identity Server running elsewhere and then back again. An API server offering up REST endpoints to the client (an Angular 5 application) is consistently the middleman managing crosstalk between the Identity Server and Angular 5 while also largely passing communications through. Identity Server has a concept of "scopes" which are URLs allowed as sources for requests. Sources of communication outside of the scopes get an applicable denial message and this is a friendlier user experience than just blocking outsiders without an explanation by way of CORS so CORS is just left open at the API server and also left open at the Identity Server where it too could be configured in favor of just letting the scopes do the safeguarding one might normally associate with CORS. When one first logs in one is given both an authentication token and an identity token. The identity token acts as a bearer token affirming your login credentials and that you may at least log in. The authentication token is not refreshed, but the bearer token is sent back to the server every five hundred seconds where it is affirmed (or rejected) and then, if affirmed, sent back to the client to replace the now no longer current old token. One may log in, leave the browser untouched for a day, and still be logged in when they return to the browser after being bailed out of jail for a DUI in this shape of things. The authentication token may be consumed as an any type in TypeScript (Jeff and Kevin do this) and therein there will be a .role hanging off of it which is an array of strings. This is used for "claims" which is a grocery list of details about who the user is. My name is Tom. I am an administrator. And so on... The claims may be used to drive things at the UI like whether or not the History Eraser Button from Ren & Stimpy shows up to begin with, but if, as an administrator, I click the History Eraser Button and I send a request back to the API server and then the Identity Server does not actually deem that I'm an administrator it could deny my request. As the authentication token is not getting recreated until I log out and log back in again, how will I be forbidden from doing things I should not be doing when I am spending the day in jail with a DUI and my boss downgrades my permissions at the server while I am away? Well, the requests to the server coming from REST calls will be blocked even if the UI still shows the History Eraser Button, right? Don't stress too hard about permissions at the client. At worst, permission woes therein make for a bad user experience. At the API server or Identity Server however and in contrast lax security can... well, you don't need a speech from me. Sanity check every request coming across the wire. Trust nothing. Another interesting thing to come up in this talk was NSwag, a tool for consuming the Swagger notes for an API and auto-generating the boilerplate code for a service for an Angular 5 app to talk to the API in TypeScript. Jeff and Kevin use this. They have an HttpInterceptor in their Angular 5 frontend to inject JWT tokens into every REST call rather than doctoring up generated code by hand which would be ghetto and hard to maintain.
Array.filter
A pretty good example of Array.filter is given here, namely:
var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);