Saturday, September 30, 2017

September Queso

  1. Dynamic-link library is what DLL stands for in a .dll file.
  2. I think perf means to perfect performance.
  3. Lotus Notes and Lotus Ami Pro where IBM's versions of Microsoft Outlook and Microsoft Word respectively.
  4. If you have an iPhone and your friend has an iPhone and you have been doing the iMessage thing with each other and your friend then decides to buy a Samsung phone while keeping the same phone number a strange thing happens. You will be able to text her, but when she texts you back you will not receive the communications. On her end it will look like the text just went through alright however. The way to fix this problem is for you to delete your entire texting thread with her and then start up a new thread.
  5. Cosplay is the whole art of dressing up as your favorite TV, movie, cartoon, or comic book character and faulting your awesome costuming skills while wandering around a tradeshow convention floor somewhere booth to booth nonchalantly as if you were there to look at things instead of being looked at yourself.
  6. An Alexa ranking is for SEO legitimacy and state of play, etc. I think the lower the number the better.
  7. Fuel Buddy is an app for managing business expenses around gassing up.
  8. I have heard that pornographic films are now exclusively named with SEO in mind with all of the words that make up a name such as "stepdaughter" being things that might be searched for.
  9. Teespring (teespring.com) supposedly lets you design your own T-Shirts.
  10. tv4-reporter is an npm package for unit testing JSON schemas.
  11. A mainframe is a huge clunky old computer running business critical software.
  12. copypasta is an ugly term for copied code, prose, etc.
  13. DocuSign provides electronic signature stuff.
  14. Cat 5 cable (or Category 5 cable) is what we used for an internet connection back before wireless was everywhere. A Cat 5 cable would run from your laptop to your router and then a coaxial cable would run to the cable TV port on the wall of your apartment from the router. The coaxial cable half of the wire up still exists.
  15. DVR stands for digital video recorder and TiVo is a famous brand of DVR. With a DVR you may digitally record TV shows. It is the modern/digital counterpart to making a bunch of VHS (video home system) tapes with a VCR (videocassette recorder) in an analog manner.
  16. COBOL stands for common business-oriented language and is an old scripting language. It seemed like this would never go away, but I've finally stopped hearing about it and JFK's assassination.
  17. Zipcar is some sort of car sharing service.
  18. I remember reading some thing once that suggested that the sooner a bug is caught the less expensive it is in terms of both money and time to turn around. It is better if you catch your own bug in your unit testing as a developer than it is if the testing teaming finds it and obviously it's better for the testing team to find it than for it to be found in production. The thing I cannot really remember had more than just these three rungs in its ladder, but you get the idea, etc.
  19. Zello allows you to use your cell phone like a walkie-talkie.
  20. I don't really understand RAM Doubler and Virtual Memory and how they sorta extend memory.
  21. Adobe is in retreat? These guys sure seemed on top of the tech world ten years ago. Flash was the way to do video, then Steve Jobs decided it would not be allowed onto the iPhone. (You know if you were to compare the history of JavaScript to say, the Bible, then the most important moment in time, birth of Christ, seam between the new testament and the old would be this moment in time.) JavaScript's star rose and Adobe's fell. Flat UIs and Twitter Bootstrap and glyphicons allow frontend talent to just sidestep Photoshop! Ten years ago it was common to see apps that made PDFs in reporting, but I don't really see that anymore.
  22. There will be wireless chargers with the iPhone X. You set the phone on a little device and it charges up.
  23. Bandsintown is an app that tells you about bands in town.
  24. Mavenlink and projectmanager.com are tools for, yes, managing projects.
  25. Nintex has to do with forms for SharePoint. Keystyle has forms and other helpers for Viewpoint. Viewpoint Field View is a similar Viewpoint thing.
  26. I learned today that the iPad 1 is no longer upgradable and you cannot download new apps for it. You are just stuck with what you had to begin with. What is more my iPhone4S which I've had since the end of 2011 is similarly about to become unsupported. The cut off has something to do with new devices being 64 bit.
  27. I once heard "petri dish" used as slang term for a dangerous environment to potentially get a computer virus. That was with regards to BBSs (Bulletin Board Systems). I'm sure this is really a thing though, the slang term.
  28. You can't upload photos to Instagram from your PC. You have you use the mobile app. There may be a hack to get around this, but this is how things are intended to be.
  29. There is a distinction between Nintex Forms and Nintex Workflows and changing a form can sabotage workflows that are midstream through a process. (for example: an approval process) Nintex has support for offline forms whereas Keystyle's approach to forms does not. Lookup lists cannot be used with more than two thousand items in the mobile space at Nintex Forms as beyond this threshold things start to crash. Nevron (pronounced: "never on") has tools for business intelligence.
  30. A Visual Studio 2015 Database Project will have a .sqlproj file instead of a .csproj file.
  31. BSOD as an acronym means "Blue Screen Of Death" and may be used like a verb. Example: "My machine just BSODed."
  32. An .art file seems to be graphics with AOL's own compression. You use their tools to look at these.
  33. Wikipedia says: "Alexa is an intelligent personal assistant developed by Amazon"
  34. Nintex Forms' mobile app does not allow you to edit a list item in "Forms" but you may assign someone one of the "Tasks" to edit an existing item. "Forms" is only for adding new items. "Tasks" cannot be part of workflows.
  35. I read a tweet that suggested that React, Jest, Flow, and Immutable.js will be relicensed under the MIT (Massachusetts Institute of Technology) license which is very permissive for free use of software. So what are Jest and Flow? Flow is some sort of type checker, pointing out errors in your code. Jest is a testing platform.
  36. HelloTalk is an app like Rosetta Stone that helps you learn a new language, but this one does what it does with Facebookesque social media organization. There are groups for different languages and one's skill level within a language, etc. You fall into chats with other people.
  37. CCleaner gets rid of local history and does some other clean up stuff. Someone hacked this tool and put a virus in it which is a barrel of laughs.
  38. https://www.npmjs.com/package/angular2-csv (i.e. "angular2-csv") is a package for rendering out .csv files from an Angular 4 app.
  39. The cgi-bin folder was where your Perl scripts went in your web site back in the mid-1990s. CGI stands for Common Gateway Interface herein.
  40. Espresso is used for writing Android UI tests.
  41. SSAS (SQL Server Analysis Services) is a tool for OLAP databases and data mining! If SSRS and SSIS are Snow White and Cinderella then this is the Sleeping Beauty other/third princess in that set.
  42. SSRS Report Builder is a tool for making SSRS reports that is a bit lighter in footprint than BIDS.
  43. Rakuten Viber is some sort of messaging app. You can make "phone" calls with it too, like Skype.
  44. Wikipedia says: "Quantum computing studies computation systems (quantum computers) that make direct use of quantum-mechanical phenomena, such as superposition and entanglement, to perform operations on data. Quantum computers are different from binary digital electronic computers based on transistors."
  45. Hapi is a JS framework for building apps.
  46. It's possible to take a bit of a song and make your own ringtone with it on the Android platform.
  47. Sling Media Slingbox is something like the fire stick Amazon offers.
  48. "Pirates of Silicon Valley" was a pretty good made for TV movie. I shows Apple stealing the idea for a GUI interface from Xerox and then Microsoft stealing it from them.
  49. Twitter is testing letting users tweet with 280 characters. There is a hack using the Tampermonkey browser that should allow you to do it if you don't have it by default.
  50. OSS is... open source software?
  51. A nibble is a half-byte or a tetrade. It's four bits.
  52. A mixin in LESS kinda lets you take in a variable in a method/function signature (so to speak) and then assign the variable to styles. Sass has mixins too.

Failed to load http://www.example.com: The 'Access-Control-Allow-Origin' header contains multiple values '*, *' but only one is allowed. Origin 'http://www.example.com' is therefore not allowed access.

Access-Control-Allow-Origin: *

...is getting added twice to a header and that is making Google Chrome cranky. I was helping a friend with this today. In her case she was specifying settings for CORS in both Web.config and Startup.cs and the double-up effect was thus a reality.

Thursday, September 28, 2017

How may I have a cascading CSS effect from a parent component to a child component in an Angular 4 application?

This allow for divs in a child component nested in an article tag in the parent component to be styled:

article ::ng-deep div {
   border-top: none;
   border-bottom: none;
}

 
 

The ::ng-deep combinator is new as of version 4.3.0 of @angular/core and I feared that it would only work in the styles metadata property for a component in a blob of embedded gunk inside of backticks and not in a stylesheet looped in at the stylesUrls metadata property which directly references a standalone Sass or LESS (Leaner CSS) or, I dunno, Stylus file. This would be bad because you cannot have a hodgepodge of stuff in the styles metadata property and stuff at the stylesUrls metadata property too, but as it turns out you may get away with ::ng-deep in the external files.

adjacent sibling combinator in CSS

If there is a section tag immediately followed by an article tag then both tags will be colored red by this:

section + article {
   background-color: red;
}

 
 

I have kind of already touched on this here but one thing new I will add is that I there does not seem to be a way to do a cascading effect with an adjacent sibling combinator. While...

article select {

 
 

...would affect just the select tags inside of an article tag. There does not seem to be a way to have something like...

(section + article) select {

 
 

...if you get my drift. Lame!

good customer service

"Hello sir! Welcome to Walgreens! Is there anything I can do for you? Anything at all?" See that's how it's done. That's good customer service. Try to make things easy on those you serve. Duh! Probably my worst trait as a developer is that I'm bad at merging. I have lived my life trying to avoid tough merges by checking in early and often. If you are going to add three new files to a Visual Studio solution why not make new nude files and then check them in right away so as not to have a merge collision with another developer at the .csproj files you dirtied up before fleshing the files themselves out with code in methods and the like? At my present job we are branching off of a main trunk, making changes and then merging back. This is a first for me. When a branch has been lingering detached from the greater reality for more than a month it is almost impossible to move back, and, you know what? ...it has been deemed better to just make a new branch at that point, splice your changes in, and then sync up that branch. There is just a philosophy that merging shouldn't be painful and that if it is there is something wrong. Most companies gave up on branching a long time ago given a perception that it is painful and instead there is a tendency to dog pile code into a QA branch and then eventually promote the QA branch to another environment when everyone has tested it. Now herein it is really easy to have merge collisions with others if you are not checking in early and often. I guess here too you can always throw away your changes if they have been too long lingering, download code anew, and then doctor your changes back in. This has never really occurred to me until recently as for the most part I've always had a preventative mindset of trying not to get painted into corners where merges are tough. Alas, both two jobs ago and the job before that too I could not check in early and often. I just wasn't allowed and I found myself either doing it anyway and drawing scorn or screwing things up in bad merges. Why such a rule? Code reviews. We have developers doing peer code reviews in both of the tough environments (for me) and a tool like SmartBear Collaborator‎ will force you to look through all of the commits one at a time when code reviewing someone's work. Hence, it is easier to read a code review with SmartBear Collaborator‎ if there is just one big commit. Atlassian Bitbucket's pull request paradigm in contrast will just aggregate all of the commits into something easy for an approver to read and review as a report giving no disincentive for multiple commits and I sure like it better. Having just experienced this it kinda gives me a boost of confidence and takes the weight off my shoulders. It's not so much me that sucks as it is SmartBear. Stupid Bear. Bad Bear. Go hibernate and die Bear. Aaargh! Better tooling please! That is good customer service. This photo of "Tyler" (so her badge says) was taken 3/21/2016.

Wednesday, September 27, 2017

Draw little ovals around things in GIMP 2.8!

  1. Go to: Windows > Dockable Dialogs > Colors ...to pick a color.
  2. Pick the "Ellipse Select Tool" from the Toolbox and draw a selection wherever.
  3. Go to: Edit > Stroke Selection... to leave your mark.

a hacky example of dressing up a third-party control in an Angular 4 app

angular2-datatable has DefaultSorter controls for sorting the headings of tables of data. They look like this:

<mfDefaultSorter by="BirthDate">Birth Date</mfDefaultSorter>

 
 

When you click one of these controls, an up arrow or a down arrow will appear by the control's name. (an up arrow first) But, what if you want an icon with both up and down arrows to appear by the control before it is ever touched as if you say "You can touch me. I like being touched." to distinguish the sortable columns with a DefaultSorter from a column that is not sortable? Well, I found a way to jam my own logic on top of the third-party control without editing the third-party control which is generally a bad idea as it sabotages the ability to ever upgrade the third-party control or at least makes doing so prohibitively painful. To start with, I jam in a span with a CSS class to make the icon like so:

<mfDefaultSorter by="BirthDate">Birth Date<span class="whatever"></span></mfDefaultSorter>

 
 

Alright, we need our own click event at the DefaultSorter and the span tag inside needs to become a ViewChild variable back at the component that governs the template into which the HTML for the DefaultSorters sit.

<mfDefaultSorter by="BirthDate" (click)="dressUpDefaultSorters($event)">Birth Date<span #birthDate class="whatever"></span></mfDefaultSorter>

 
 

For argument sake let's say there are three sortable columns leading to three ViewChild variables like so:

@ViewChild('birthDate') birthDate: ElementRef;
@ViewChild('deathDate') deathDate: ElementRef;
@ViewChild('barMitzvah') barMitzvah: ElementRef;

 
 

Alright the dressUpDefaultSorters method in the component looks like so:

dressUpDefaultSorters(event:any):void{
   let classForDoubleArrowIcon:string = "whatever";
   [this.birthDate, this.deathDate, this.barMitzvah].forEach((defaultSorter:ElementRef)=>{
      defaultSorter.nativeElement.className = classForDoubleArrowIcon;
   });
   let nodes = event.toElement.childNodes;
   if (nodes.length == 0){
      if (event.toElement.className == classForDoubleArrowIcon){
         event.toElement.className = "";
      }
   }
   event.toElement.childNodes.forEach((node:any)=>{
      if(node.className == classForDoubleArrowIcon){
         node.className = "";
      }
   }); }

 
 

Alright, one tacky thing about DefaultSorters is that if you click one, the arrow disappears from the others that have been clicked so we need to put the double arrow back on the other columns which is the first thing we do above. Then we determine if one clicked upon the DefaultSorter itself or the span within the DefaultSorter and apply the whatever class as applicable. Nasty? Maybe so.

 
 

Addendum 9/29/2017: Alright, since writing what is above I have found a mistake and, no, it's not that the last curly brace isn't on its own line though that sucks too. The problem is that if you click on the standalone up or down arrows that are provided with the DefaultSorter tags that you are clicking on a span inside the tag and not the tag itself and my code does not account for that. There is a fix and it's not pretty. The dressUpDefaultSorters method is going to need a second input like so:

<mfDefaultSorter by="BirthDate" (click)="dressUpDefaultSorters($event,'birthDate')">Birth Date<span #birthDate class="whatever"></span></mfDefaultSorter>

 
 

We need to use the magic string like so:

dressUpDefaultSorters(event:any, name:string):void{
   let classForDoubleArrowIcon:string = "whatever";
   let columns:Array<ElementRef> = [];
   if (name != 'birthDate') columns.push(this.birthDate);
   if (name != 'deathDate') columns.push(this.deathDate);
   if (name != 'barMitzvah') columns.push(this.barMitzvah);
   columns.forEach((defaultSorter:ElementRef)=>{
      defaultSorter.nativeElement.className = classForDoubleArrowIcon;
   });
   let nodes = event.toElement.childNodes;
   if (nodes.length == 0){
      if (event.toElement.className == classForDoubleArrowIcon){
         event.toElement.className = "";
      }
   }
   event.toElement.childNodes.forEach((node:any)=>{
      if(node.className == classForDoubleArrowIcon){
         node.className = "";
      }
   });
}

How do I turn off a width or height setting in CSS by stamping over top of it?

width: auto; is good for overpowering width: 100%; if you want to throw away the specific setting when it is assigned as part of a bigger bag of settings (i.e. a class).

Tuesday, September 26, 2017

how to use ViewChildren in an Angular 4 app

boxes as suggested here, is going to accessible as an array of controls like so:

this.boxes._results[13].nativeElement.value = 42;

What does the default keyword in Angular 2 do?

As suggested here, something like this:

export default class InnerGridComponent {

 
 

May be looped in like:

import InnerGridComponent from './innergrid.component';

 
 

Whereas something like so:

export class InnerGridComponent {

 
 

Would be looped in like:

import {InnerGridComponent} from './innergrid.component';

 
 

In the second approach one could have numerous classes in the same file and then loop them in with one import statement, separating the class names with commas inside of the curly braces.

Create a pull request in Atlassian Bitbucket's paradigm.


  1. Log in as you at: https://bitbucket.org/
     

  2. At the far right is a list of repositories. Click on the applicable repository.
     

  3. The page will change and at the upper left you will see a vertical list of nav items. One of them is "Pull requests" and you should click upon it.
     

  4. The next page that comes up is kinda nude save for a button that reads "Create pull request" at the far upper right. Click the button. (It is a little hard to notice at first.)
     

  5. There is a little form to fill out that appears. Select where you want to pull from and where you would like your code to be pushed to. In the "Reviewers" field, type in the name of a reviewer. The interface should hopefully match up what you type with a real choice. Finally, click the "Create pull request" button.
     

  6. You'll get an email telling you when your request is approved or declined and if it is approved and declined. Obviously, you have to wait for the reviewer to act before you get such an email.

SEO challenges with Angular 4?

Angular is bad for SEO? Well maybe so. There is server-side loading to try to make a web site more crawlable. You cannot use lazy loading with it and you will want to use HostListener and HostBinding to manipulate DOM elements and not, for example, injected jQuery. Grabbing ahold of elements and wrangling them while using server-side loading is a little trickier.

Monday, September 25, 2017

How do I get the width of an ElementRef in Angular 4 at the TypeScript side?

Assuming whatever is an ElementRef...

getTheWidthOfWhatever():number{
   let nativeElement:HTMLElement = this.whatever.nativeElement;
   let wideness:number = nativeElement.offsetWidth;
   return wideness;
}

 
 

There is also an .offsetHeight too.

using style. inline at a tag in Angular 4

Alright, first off let's talk about what this is not. This is not ngStyle (though you will represent styles with a hyphen normally of kebab-case in camelCase instead just the same), but instead this is the way to set a style while reaching back to a TypeScript method at a component from the component's template. At the template one might have:

<button type="button" [style.marginLeft]="getMargie()" (click)="act()">X</button>

 
 

...and then getMargie could look like:

getMargie():string{
   return "42px";
}

 
 

Obviously, there is little reason to have something so simple. You would have TypeScript side mechanics to calculate the string that this method returns or else there is no reason to do something like this whatsoever. Anyhow, what is above will work great, but no matter what you do, do NOT do something like this:

getMargie():string{
   return "42px;";
}

 
 

See the difference? The semicolon inside the string is bad, bad, bad.

Sunday, September 24, 2017

Reducers versus Effects in the NgRx paradigm

A reducer transforms state and does it synchronously. If you need to run any other sort of code in a similar vein you use an effect, and this could be anything that does not affect state.

Saturday, September 23, 2017

What lends the spread operator in TypeScript to immutability per se?

Well, consider this:

let yin = [13, 42];
let yang = [69, 86];
let yinyang = [...yin, ...yang];
console.log(yinyang);

 
 

It spits this up to the console in Google Chrome Development Tools:

  1. Array(4)
    • 13
    • 42
    • 69
    • 86

 
 

If we expand the code to this:

let yin = [13, 42];
let yang = [69, 86];
let yinyang = [...yin, ...yang];
console.log(yinyang);
yinyang[2] = 0;
console.log(yinyang);
console.log(yang);

 
 

We get this:

  1. Array(4)
    • 13
    • 42
    • 0
    • 86
  2. Array(4)
    • 13
    • 42
    • 0
    • 86
  3. Array(2)
    • 69
    • 86

 
 

And furthermore this:

let yin = [13, 42];
let yang = [69, 86];
let yinyang = [...yin, ...yang];
console.log(yinyang);
yinyang[2] = 0;
console.log(yinyang);
console.log(yang);
yang[0] = 13;
console.log(yinyang);
console.log(yang);

 
 

Gives:

  1. Array(4)
    • 13
    • 42
    • 0
    • 86
  2. Array(4)
    • 13
    • 42
    • 0
    • 86
  3. Array(2)
    • 13
    • 86
  4. Array(4)
    • 13
    • 42
    • 0
    • 86
  5. Array(2)
    • 13
    • 86

 
 

Neato! A change to the arrays' numbers does not affect the values in the other arrays. Now let's try the same trick with some objects:

let yin = {
   foo: 13,
   bar: 42
};
let yang = {
   bar: 69,
   baz: {
      qux: true
   }
};
let yinyang = {
   ...yin,
   ...yang
};
console.log(yinyang);

 
 

What is immediately above gives us:

  1. Object
    • bar: 69
    • baz:
      • qux: true
    • foo: 13

 
 

Alright, so far so good. Now consider this:

let yin = {
   foo: 13,
   bar: 42
};
let yang = {
   bar: 69,
   baz: {
      qux: true
   }
};
let yinyang = {
   ...yin,
   ...yang
};
console.log(yinyang);
yinyang.bar = 86;
yinyang.baz.qux = false;
console.log(yinyang);
console.log(yang);

 
 

Well that yields:

  1. Object
    • bar: 86
    • baz:
      • qux: false
    • foo: 13
  2. Object
    • bar: 86
    • baz:
      • qux: false
    • foo: 13
  3. Object
    • bar: 69
    • baz:
      • qux: false

 
 

Oh no! Trouble in paradise! This kinda works, but the objects that are copied are not deep copied leading to some unexpected behavior. Notice that all qux settings end up as false. What is more...

let yin = {
   foo: 13,
   bar: 42
};
let yang = {
   bar: 69,
   baz: {
      qux: true
   }
};
let yinyang = {
   ...yin,
   ...yang
};
console.log(yinyang);
yinyang.bar = 86;
yinyang.baz.qux = false;
console.log(yinyang);
console.log(yang);
yang.bar = 0;
yang.baz.qux = null;
console.log(yinyang);
console.log(yang);

 
 

Gives us:

  1. Object
    • bar: 86
    • baz:
      • qux: null
    • foo: 13
  2. Object
    • bar: 86
    • baz:
      • qux: null
    • foo: 13
  3. Object
    • bar: 0
    • baz:
      • qux: null
  4. Object
    • bar: 86
    • baz:
      • qux: null
    • foo: 13
  5. Object
    • bar: 0
    • baz:
      • qux: null

Friday, September 22, 2017

There is a distinction between simple and searched case statements in T-SQL.

The searched approach uses conditional operators to arrive at true or false for which branch to take as suggested here. The simple approach is more like a case/switch statement. This has this example which seems to use the AdventureWorks database which is some dummy database that is used in dummy scenarios like the Northwind database.

USE AdventureWorks2012;
GO
SELECT ProductNumber, Category =
      CASE ProductLine
         WHEN 'R' THEN 'Road'
         WHEN 'M' THEN 'Mountain'
         WHEN 'T' THEN 'Touring'
         WHEN 'S' THEN 'Other sale items'
         ELSE 'Not for sale'
      END,
   Name
FROM Production.Product
ORDER BY ProductNumber;
GO

 
 

You may have an OR or an AND in a searched case statement like so:

WHEN Yin > 13 or Yang < 42 THEN 'Meh'

Pull settings out of the columns of a SharePoint list with Nintext tasks to push records back to an MSSQL database.

This is doable. I don't really understand it end to end yet. The markup looks something like so:

UPDATE DeathNotice SET
EffectiveDate = '{ItemProperty:Effective_x0020_Date}',
Explanation = '{ItemProperty:Explanation}',
SupervisorComments = '{ItemProperty:Supervisor_x0020_Comments}',
ContactPhone = '{ItemProperty:Phone}',
IsCompleted = 1
WHERE DeathNoticeID = '{ItemProperty:Death_x0020_Notice_x0020_ID}'

 
 

_x0020_ here represents a space in the name of a column.

 
 

Addendum 9/25/2017: It's Nintex not Nintext. (groan)

npm run whatever

A command line command of "npm run " (assuming you are using Webpack in an Angular 4 app) followed by a keyword as a third word will run the property with the third word's name in the object at the scripts property in package.json at the immediate folder.

Wednesday, September 20, 2017

syntactic sugar for nullable types in C#

What's the difference between...

DateTime? itsYourBirthday = null;

 
 

...and...

Nullable<DateTime> itsYourBirthday = null;

 
 

...in C#? Nothing? There is no difference. This says: "The former is syntactic sugar for the second."

Tuesday, September 19, 2017

If ngModel is used with a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.

This Angular 4 error suggests you are associating an [(ngModel)] with something that is not an attribute. A hierarchical naming drill down will not work here.

Find tickets in your court for a particular project in Jira's web interface.

Go to "View all boards" under the "Boards" option at the top nav. Then pick an board. The tickets that appear will be organized by teammate name so scroll down until you see your name.

What's the difference between a data source and a server in a connection string?

Nothing! This suggests these five things are "entirely equivalent" FYI:

  • Data Source
  • Server
  • Address
  • Addr
  • Network Address

How do you use LinqToExcel if there are no named columns?

If your columns are just named, A, B, C, etc. then this makes things trickier as these default titles will not be recognized with this trick and thus you cannot do something like this to map the rows to a collection of a custom type. You can however map the rows to a collection of RowNoHeader (which is a type LinqToExcel has) and then loop through the records and make a list of your own custom type like so:

public List<History> GetWeldLogs(string pathToFile)
{
   var excelSheet = new ExcelQueryFactory(pathToFile);
   IQueryable<RowNoHeader> logs = from x in excelSheet.WorksheetNoHeader("Log")
         select x;
   List<History> histories = new List<History>();
   foreach (RowNoHeader log in logs.ToList())
   {
      History history = new History();
      history.Note = log[12].Value.ToString();
      histories.Add(history);
   }
   return histories;
}

 
 

This may look like the thirteenth column is being mapped off to Note, but honestly it will only be the thirteenth column that has data. If there are completely empty columns they will not go into this count and may throw your count off.

If you close a tab in Atlassian SourceTree...

Well, if the project was ever open as a tab to begin with, there will be a link at the leftmost nav for reopening the tab. If you delete the .git and .gitignore from where your files are stored accidentially a tab may disappear on you. Restore from your Recycle Bin and then reopen the tab.

Sunday, September 17, 2017

the new HttpClient in Angular 4

  1. You import HttpClientModule, at both your module and your component, like so:
    import { HttpClientModule } from '@angular/common/http';
    and a private http: Http variable becomes private httpClient: HttpClient at your component. You no longer need Http and Response. Response may be sidestepped as it is now much easier to map off what you get back like so:
    this.httpClient.get("http://www.example.com").map((foo:Foo) => {
    ...and like so...
    this.httpClient.get<Foo>("http://www.example.com").map((foo) => {
    ...these are examples of: "Typed Requests"
  2. Remember how in ASP.NET MVC how you didn't necessarily have to communicate in JSON and you could instead set messaging to be in XML? Well, there is no XML support with the new HttpClient, but it does allow for a few variations from JSON. You may add a second options parameter to a get call like so:
    this.httpClient.get("http://www.example.com", {
       observe: body,
       responseType: 'text',
    }).map((foo) => {

    This is going to scrape the guts of whatever there is to see as text (even if it is JSON) and return it in kind. Other options for responseType are "blob" for a file, "json" which is the default and which you don't really need to explicitly state, and, finally, "arraybuffer" too. A combo of "response" for the observe setting and "text" for the responseType setting does something similar but the text that comes back seems to be interpreted as one big string in a JavaScript object instead of merely text alone. Beyond "observe" and "responseType" other parameters for this options object include "headers" for passing headers and "body" for passing an outbound package as is the case in .put implementations. In using a .put instead of .get, the options will typically be the third parameter (the two beforehand being first the URL and the second the object you are putting out there) and not the second as in the case of a .get, but if you use "body" with a .put you may skip the second property.
  3. Setting "observe" to "event" allows for some interesting things downstream in a .subscribe, for example:
    .subscribe(
       (response: HttpEvent<Object> => {
          if (response.type === HttpEvent.Sent) {

    If this is downstream of a .put, which, yes, has to have a response come back in the Angular way of doing things as if someone is putting pins in Roy Fielding's voodoo doll (PUT should be fire and forget) well then the if statement is gonna get hit twice. First the event out to the endpoint will successfully meet the criteria in the .Sent and then the response back will not. This allows you to pry into events. Beyond "Sent" there is "Response" and "User" and "ResponseHeader" and "DownloadProgress" and "UploadProgress" too. If you log response.type to the console, Sent has a type of 0, UploadProgress a type of 1, and DownloadProgress a type of 3 so there is a numeric encoding behind these guys. Loop in HttpEvent like so:
    import { HttpEvent } from '@angular/common/http';
  4. headers: new HttpHeaders().set("foo", "bar").append("baz", "qux")
    ...is the way to do the headers and you can loop them in with...
    import { HttpHeaders } from '@angular/common/http';
    ...and also you may make a standalone HttpHeaders const variable that you assign in lieu of the immediate assignment.
  5. params: new HttpParams().set("key", "value")
    ...is how you similarily add, cleanly, the URL line parameters without actually jamming them in the URL line. Loop HttpParams in like so...
    import { HttpParams } from '@angular/common/http';
  6. const act = new HttpRequest('PUT', 'http://www.example.com', this.myThing, {});
    this.httpClient.request(act);

    ...is another shape of things and if you put...
    reportProgress: true
    ...in the options you will be able to listen for the upload and download events.
  7. import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest }
          from '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    export class WhateverInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          return next.handle(httpRequest);
       }
    }

    ...is an example of an interceptor. You would put this is its own file and whatever.interceptor.ts would be a pretty spiffy name. You will loop this into a module and all of the REST calls that use this new approach that the module governs will use the interceptor midstream in calls! Import the following at a module:
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    You loop this in a providers in the module by giving an object as an array item instead of a name per the norm. (If you have more than one interceptor in providers then they will be run in the order specified sequentially in providers.) The object is:
    {provide: HTTP_INTERCEPTORS, useClass: WhateverInterceptor, multi: true}
  8. import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
          '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    export class WhateverInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          const copy = httpRequest.clone({headers:
                httpRequest.headers.append('yin,'yang')});
          return next.handle(copy);
       }
    }

    ...is a way to add a header to all outbound requests and you may also add a param all the time like so...
    import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
          '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import { Injectable } from '@angular/core';
    import { TokenService } from from '../services/token.service';
    export class WhateverInterceptor implements HttpInterceptor {
       constructor(private tokenService: tokenService) {}
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          const copy = httpRequest.clone({headers:
                httpRequest.params.set('token,this.tokenService.giveToken())});
          return next.handle(copy);
       }
    }
  9. import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
          '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/do';
    export class WhateverInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          return next.handle(httpRequest).do(
             thing => {
                console.log(thing);
             }
          );
       }
    }
    ...has you writing stuff to the console for every event. Note that we are using a .do and not a .subscribe as .subscribe actually consumes the Observable in scope and would sabotage a later .subscribe.
  10. https://angular.io/guide/http has some documentation and, again, all of the notes here were stolen out of an online training I watched.

a toy

I am enjoying this interesting piece of swag. It's life support for my iPhone. I tried it today for the first time and it works great. It kept my phone charged at 100% while I drove across Houston while repeatedly playing http://youtu.be/LVB2mXCTbNs over and over again. It should help me stay alive at a convention, the ultimate test of battery life. The little wire powers the device at the smaller port and the larger port powers my iPhone. Yay!

ngrx allows for the Redux pattern in Angular 4

Get it here. With this approach you have a pattern wherein services and components go to a common store for all data and the store is specifically only ever updated by the firing off of "Actions" which then go through "Reducers" which might transform them. I've been going through a series of online trainings for Angular 4 and I learned this today from them.

Friday, September 15, 2017

Flip JPEGs in GIMP to their mirror images and also rotate them in 90 degree increments.

Image > Transform ...in GIMP 2.8 will allow for these transformations. There is also a Guillotine option here that I don't understand yet. I think it has to do with breaking up an image for the web into smaller images in the way Adobe Fireworks once did.

using System.Configuration;

You have to add this reference into a C# Console App to fish stuff out of the AppSettings with it in Visual Studio 2015. This shocked me. Well, perhaps shock is hyperbolic. I raised an eyebrow (though not literally).

when you right-click on a test project in Visual Studio 2015 and the "Run Unit Test" option isn't there

Build the project to fix this.

Thursday, September 14, 2017

How do I set the color of the text in a C# console app?

if (resultOfAct.IsSuccessFul)
{
   Console.ForegroundColor = ConsoleColor.Green;
}
else
{
   Console.ForegroundColor = ConsoleColor.Red;
}

 
 

Gray seems to be the default color, not White.

generic, hacky, let's-update-the-database thing in C#

using System.Data.SqlClient;
using WelderConsoleApp.Interfaces;
namespace WelderConsoleApp.ExternalDependencies
{
   public class DatabaseManipulations : IDatabaseManipulations
   {
      public void UpdateGetWelderData(string connectionString)
      {
         using (SqlConnection sqlConnection = new SqlConnection(connectionString))
         {
            using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
            {
               sqlCommand.CommandText = "UPDATE Employee SET WelderStencil =
                     @value WHERE HRRef = @key";
               sqlCommand.Parameters.AddWithValue("@key", "215527");
               sqlCommand.Parameters.AddWithValue("@value", "yay");
               sqlConnection.Open();
               sqlCommand.ExecuteNonQuery();
               sqlConnection.Close();
            }
         }
      }
   }
}

IS keyword in T-SQL?

SELECT * FROM Yin WHERE Yang is not null

...is the way to do a select to not find null stuff and not...

 
 

SELECT * FROM Yin WHERE Yang <> null

...and this kinda surprised me. I was expecting to rock the <> Not Equal To comparison operator.

anonymous methods in C# can be used with actions

Consistent with using an anonymous method with a Func you may also use them with an Action.

(string whatever)=>{}

 
 

...will play nicely in being assigned to:

Action<string>

In a C# console app, Console.Write may be handed into an Action of string to log to the console in code beyond the Main method in the Program class.

Your deeper mechanics, deferred to in other files, may just take an Action<string> at their method signatures to accomodate this.

Code generated using the T4 templates for Database First and Model First development may not work correctly if used in Code First mode. To continue using Database First or Model First ensure that the Entity Framework connection string is specified in the config file of executing application. To use these classes, that were generated from Database First or Model First, with Code First add any additional configuration using attributes or the DbModelBuilder API and then remove the code that throws this exception.

This error comes up when attempting to talk to an .edmx in lieu of going Code First with Entity Framework (i.e. Model First or Database First) and having a connection string that is not formatted in a Model First friendly way. The following is an example of the right was of talking to an .edmx named Foo.edmx in a Models folder somewhere:

<add name="FooEntities" connectionString="metadata=res://*/Models.Foo.csdl|res://*/Models.Foo.ssdl|res://*/Models.Foo.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=www.example.com;initial catalog=whatever;User ID=god;Password=letmein;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient"/>

 
 

Note that what you might normally think of as the connection string is wrapped in &quot; bookends and there is some extra gunk wrapping it.

Wednesday, September 13, 2017

Fish a single property deeply nested in a JSON file out with a JavaScriptSerializer in C#!

public string GetConnectionString(string pathToFile)
{
   string text = System.IO.File.ReadAllText(pathToFile);
   JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
   var jsonObject = javaScriptSerializer.Deserialize<dynamic>(text);
   return jsonObject["Data"]["DefaultConnection"]["ConnectionString"];
}

how to query with LinqToExcel

To use this stuff, do something like so:

var excelSheet = new ExcelQueryFactory(myPathToFile);
IQueryable<Foo> welders = from f in excelSheet.Worksheet<Foo>("Sheet1")
      where f.Bar != ""
      select f;

 
 

Also: In Visual Studio 2015, right-click on the project and pick "Properties" and then click "Build" at the left nav of the pane that appears. Set the "Platform target:" from "Any CPU" to "x86" which is needed as Excel is a thirty-two bit application.

Manually update an Entity Framework .edmx file.

This approach can be overkill. If you are just adding a column to a table, open the GUID editor for the .edmx in Visual Studio 2015 and add the new column there. The properties pane in Visual Studio 2015 will let you define if the column is null and how many characters it may be, etc. Then open the .edmx in Notepad and splice in the change in three places:

  1. the EntitySetMapping with your table name
  2. the EntityType under Schema under edmx:StorageModels at the beginning of the file with your table name
  3. the EntityType under Schema under edmx:ConceptualModels farther down the file with your table name

 
 

One of these three changes happens as a side effect of your GUI change, but I cannot remember which. It should be pretty easy to figure out how to add a column in all three places. You just copy from the existing columns and do doctor ups.

I worked with a Visual Studio Database project for the first time today.

In Visual Studio 2015, such a project will have a "dbo" folder and inside of this folder there will be folders for "External Tables," "Functions," "Stored Procedures," "Tables," and "Views" and the "Tables" folder has create scripts for the various tables. If you splice in a column here there is a RedGate Data Compare flavored means for generating a comparison script to be deployed to an environment that has everything but the bit you are bolting on.

Console.ReadKey(true); versus Console.ReadLine();

Getting back into console apps in Visual Studio 2015, Console.ReadLine() now, no longer, seems to react to any key being pushed in the same way. Basically you proceed if you press Enter, but if you just type copy the copy appears right there in the console. Console.ReadKey(true) hides what you type in contrast and you go forward no matter what you tap on the keyboard so a "press any key" instruction better fits to this. Wait! This is not true at all. The Console.ReadKey(true) approach does not react to the press of the Enter key after all. Yeesh. So much for the "press any key" instructions. Wait again! The return key for Console.ReadKey(true) is only sabotaged for me in this fringe scenario.

Make a unit test project double as a console app in Visual Studio 2015!

Make a unit test project and add in a Program.cs file for the head of the console app to be:

using System;
namespace MyApplication
{
   class Program
   {
      static void Main(string[] args)
      {
         Console.Write("Welcome to the application.\r\n");
         Console.Write("Press almost any key to end the experience.");
         Console.ReadKey(true);
      }
   }
}

 
 

Make an App.config also:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <startup>
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
   </startup>
</configuration>

 
 

Open up the .csproj file in Notepad and doctor this line of XML...

<OutputType>Library</OutputType>

 
 

...into this:

<OutputType>Exe</OutputType>

 
 

This last step ensures that you will not be told "A project with an Output Type of Class Library cannot be started directly." when you attempt to run the console app. Now you may either run your app or run your tests. Yay! If you were just planning to make a solution that had only two projects for tests and a for a console app, you may now make a solution with only one project! I'm not saying that this is the best idea in the world. I'm just saying you have the power.

Tuesday, September 12, 2017

parseInt will make integers of decimals without error in JavaScript.

So how do you sanity check for just an integer? Like so:

var bar = parseInt(foo);
if((!bar && bar != 0) || (foo.indexOf(".") >= 0)) {
   alert("It's not an integer!");
} else {
   alert("I feel whole.");
}

The longer you wait to merge your branch the more terrible it's gonna be.

When your ticket is finally QA approved and it's time to go on to the next environment, you may be ahead to just branch off your environment, doctor in your five changes, and merge back the new branch instead of merging in your five changes and one hundred things that have grown apart from modern realities over a few weeks' time. If you don't take this nuanced step and you try to merge in, let's say a dozen here and there changes in an Entity Framework .edmx which have nothing to do with the change you were attempting to begin with, expect things to fall down.

If you are spending two hours on a merge something is wrong. At this point you are ahead to splice instead of merge. Both things invite catastrophe but the splicing is better.

Sunday, September 10, 2017

404 redirects can be cornerstone to Angular 4's routing.

This is kinda disappointing actually. If you don't want to use the hack wherein there is a hashtag at the beginning of a route you have to instead make 404 errors at your server reroute to your token .html page. I'm serious. Kinda ghetto, huh? It makes sense right? If you go to a route and it's just not there, how else can you communicate the route to your Angular 4 app hosted at what is honestly a completely different route as far as your hosting is concerned?

Use a second property at .forRoot to loop in the ability for progressively preloading, behind the scenes, that which will be lazy loaded.

RouterModule.forRoot(whatever, { preloadingStrategy: PreloadAllModules })

 
 

You loop this in an Angular 4 app from '@angular/router' as shown here using a second parameter for .forRoot (the first being an array of routes) which is configuration settings as suggested above and hopefully this will, in tandem with the lazy loading, will help you keep your head above water.

Friday, September 8, 2017

How can I find the balls in my court in Jira.

At: Boards > All Projects ...the left nav with show links for "Backlog" and "Active sprints" and "Reports" and the first of these two are probably what you want. "Backlog" shows what is to come in future sprints and "Active sprints" shows the swim lanes for your most immediate challenges.

Atlassian SourceTree is maximizing in such a way that it fills the lower half of the desktop only?

This is a bug. Get the latest version of SourceTree to get rid of the bug.

Thursday, September 7, 2017

resetting custom controls amid Angular 4 templates in hacking

As described here, it may be hard to manhandle third party controls which replace some of your HTML with their own HTML. I fought like mad with one today that turned checkboxes into little dressed up span tags with checkbox images in them. Anyhow, if the control appears as part of the repeating guts inside an *ngFor you can always reset the control to a default state by rehydrating the data driving the *ngFor. I did this today to uncheck a bunch of checkboxes upon the changing of tabs.

ViewChildren is kinda like ViewChild in the Angular 4 paradigm only for numerous items, perhaps repeating in an *ngFor

You loop it in with:

import { ViewChildren } from '@angular/core';

 
 

@ViewChildren('box') boxes: any; might go in a component and #box in a tag that gets repeated. I don't really understand how to make the most of this yet. This has some details.

*ngIf="0"

This is a hack to wall off a feature in an Angular 4 app from seeing the light of day. You'd put it at a component's HTML tag where applicable. This may be preferred to removing the feature if you think you are gonna circle back to the feature or you just can't kill your baby. Maybe the feature will be used, just not in the most immediate release or something like that.

incognito for Google Chrome

This is a mode you may enter by clicking Ctrl-Shift-N in Chrome. It gives you an alternate browser which will keep no browsing history or cache of browsed gunk. It is good for sandbox troubleshooting. To allow plugins in incognito I think you have to explictly turn them on at chrome://extensions/

Wednesday, September 6, 2017

feel out the gift from the wrapper

Let's say a third party control revamps an html tag, turning a select list into a bunch of span tags with some li items nested further inside. Well, that means that you can't really put Angular 4 events on the select tag and expect them to do anything as they are gonna get wiped away in the replacing of one thing with another, right? So what can you do to jam in your own events? You can wrap the disappearing thing in another tag and then put an event on it like so:

(click)="onDropDownClick($event)"

 
 

Then you can make sense of what piece of the wacky apparatus was clicked on because the classes for the bit that was clicked on will be exposed and will differ across different elements.

onDropDownClick(dd: any){
   console.log('made it this far');
   if (dd && dd.toElement && dd.toElement.className == "select2-results__option"){
      console.log(dd.toElement.textContent);
   }
}

a slightly better way of casting a string to Pascal Case in C#

CultureInfo is now just statically available in the System.Globalization namespace in C#. You don't have to fish it off the thread as suggested here. Instead you may just do something like:

TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
string Tom = textInfo.ToTitleCase("tom");

Invalid length parameter passed to the LEFT or SUBSTRING function.

This Entity Framework error means that you are trying to do an operation like .Substring(13) which in C# will remove the first thirteen characters from a string and that there are not thirteen characters to shed.

Select2 for jQuery is some sort of type-in-a-select-list-to-search-for-something widget.

I'm not sure if this or this is where to get it. It's worth a look. It's pretty mindblowing.

 
 

Addendum 9/7/2017: One thing that can really sabotage these controls is to mismap the values for the ids for the dropdown selections. If the mapping is bad and all of the hidden values just end up undefined, you will not be able to make a selection or see any hover over highlighting when you mouse over results returned from a search.

Tuesday, September 5, 2017

short attention span?

"Got your two feet walking?" is one of the idioms of open spaces style conferences. It means if you don't like a discussion you can just go to another one and no one will find it rude or out of the norm. Kerry Kimbrough once posed this question to me at one of these events.

Monday, September 4, 2017

some Angular 4 notes on modules learned from an online training

  1. It makes sense to loop in FormsModule and ReactiveFormsModule at imports in a wrapper module wrapping an application.
  2. import { CommonModule } from '@angular/common'; is a good import for a nested submodule (called a feature module) in contrast to:
    import { BrowserModule } from '@angular/platform-browser'; which is going to be the comparable thing at an outermost module. Both of these make fundamentals like *ngIf and *ngFor possible, but the BrowserModule has some extra mechanics that needs to be at the mouth of an application.
  3. When importing a routing module use .forRoot in a wrapping module and .forChild in a nested feature module.
  4. You can loop in funtionality at nested modules with a shared module which will be in the imports of both the wrapper/outer module and the nested module(s) where you want to utilize it. In such a shared module, the directive (let's say) to be looped in will be listed at both the declarations and the exports. You may also put CommonModule in the exports so you don't have to explictly loop it in at every nested module that gets the shared module.
  5. You may mention components by name in a routing module without them being in imports and without the app breaking. How is this possible? Well, as long as another module loads the component before you visit the component or give a link off to the component, you're gold. It's another thing to call a component by a selector tag however. You'd better be "in scope" for that. (have the component at the immediate module)
  6. { path: 'whatever', component: FooComponent } could be refactored as...
    { path: 'whatever', loadChildren: './stuff/bar.module#BarModule' } and assuming there is a BarModule class with an @NgModule decorator in stuff/bar.module.ts and that BarModule is the nested module that manages FooComponent well then this will allow us to lazy load FooComponent.
  7. There is a Root Injector that generally hydrates the providers in modules, both app-wide and feature-based. The same logging service instance, for example, should thus be used, as a singleton, in the wrapper God module and a given feature module and you can declare providers for the same service in both places without Angular complaining. When you get into lazy-loaded feature modules well therein it is possible to have a breakout in which a separate instance of the logging module materializes. A shared module across both a regular feature module and a lazy-loaded feature module will behave strangely using the common singleton for the regular feature module and a one off new thing for the lazy-loaded feature module.
  8. AuthGuard is one of the few examples of a service you might loop in at providers at a routing module.

Sunday, September 3, 2017

How do I save a .csv file that uses commas instead of tabs from Microsoft Excel 2013?

at Windows 10: Control Panel > Region > Additional settings... > List separator ??? No! That is where I am told to do it when I Google against this problem, but there is already a comma at that setting. I am instead hacking around this problem by creating a .csv file manually in Notepad with a few commas in it but no tabs and then opening it in Excel. When I resave the file, it honors the tabs.

no more AppDomain.CurrentDomain.BaseDirectory?

I created a .NET Core frontend project in Visual Studio 2017 and bolted on some traditional C# projects to the solution and then this trick didn't work in one of the C# class libraries for finding out where on was. AppDomain was red in Visual Studio like it could not be found. I settled for this instead:

string path = System.IO.Path.GetFullPath("Presidents.csv");

 
 

Even though Presidents.csv sat right next to the C# file I was using to find it and both files where not in the .NET Core UI, the path that came back was nonetheless a path to the folder for the UI with "Presidents.csv" bolted onto the end. Huh? I guess I don't really know how to manipulate this stuff yet. I was able to doctor the path that I was given into something I could use.

Friday, September 1, 2017

Michael Dell of Dell Computer is giving $36 million to Hurricane Harvey relief!

He is from Houston and I am in Houston (well, Deer Park) as of the last three months and change. I wish Houston native Bill Hicks was still alive to tell us some jokes. It would be a relief to have a laugh. This is the worst natural disaster in Houston's history. I worked at Michael Dell's now privatized company most recently in Austin (well, Round Rock) before the current job in Houston. It was a good experience. I got to learn trendy Angular 2/4 and work with some awesome people.

truculent

What if you want to query what is inside of a nested Angular 4 component from a wrapping component in lieu of waiting for the nested component to communicate up to the wrapping component with an EventEmitter? The way to do something like that is to make a ViewChild variable off of the nested component in the wrapping component (put a local reference at the selector tag) and then call a method off of the variable which will have to be defined in the nested component's TypeScript guts. This kinda makes me cranky and is something to probably avoid honestly. In my immediate circumstance wherein it applies to me, I need to do something upon the click of a button in the wrapping component and the nested component's checkboxes will bias the act.

@ViewChild('nestedComponent') nestedAccess: MyComponent;

 
 

...could be my ViewChild variable assuming a local reference of:

#nestedComponent

How can I tell which tab in an ARIA Tab Panel is selected in an Angular 4 app?

You can make each div with role="tabpanel" on it a ViewChild variable and then look to see if this.whatever.nativeElement.className contains the string "active" or for some comparable telling marker.

 
 

Addendum 1/12/2018: What I suggest are ARIA tabs here are actually Bootstrap 4 tabs as suggested here.