Wednesday, October 4, 2017

Assignments which accidentally use a double equals operator will not make the compiler squawk in TypeScript.

Consider this C#:

int a = 13;
int b = 42;
a = b;

 
 

And then consider introducing this typo:

int a = 13;
int b = 42;
a == b;

 
 

Alright, the compiler is going to throw a temper tantrum at that, huh? Well what if we took this TypeScript...

let a = 13;
let b = 42;
a = b;

 
 

...and screwed it up like this:

let a = 13;
let b = 42;
a == b;

 
 

Well, this may come as an unpleasant surprise (it sure did for me) but the compiler will not get cranky about this. I guess you are just dumping a comparison on a line by itself and the comparison, be it true or be it false, will just silently do nothing without any other code about it. In other words, your assignment silently fails. I guess this is legitimate JavaScript and therefore legitimate TypeScript. Fun!

What is the difference between const and let in TypeScript?

const is just like let except that you cannot reassign const variables.

Tuesday, October 3, 2017

Mandalay Bay

The only time I have been to Las Vegas, Nevada it was in 2015 for Black Hat which was at the Mandalay Bay casino. In deciding where to stay it was easy to conclude that I should stay at Mandalay Bay too and so I did. I was there for a few nights.

As of this week Mandalay Bay's name will be tied to one thing in history, the deadliest rampage killer rampage in American history. A gunman (Stephen Paddock) fired from one of the hotel rooms on the thirty-second floor outward into a Jason Aldean country music concert and then formulaically killed himself when cornered by law enforcement enforcers. Is anyone going to want to vacation here again? Are they going to have to tear down the casino and put something else in its place?

This casino is the Southernmost of all the casinos on the Vegas strip. The "Bay" part comes from a very impressive swimming pool that is there that fakes waves and what not. I have photos of it, but they really are not that good as far as photos go. I also have a not so great photo of the view out my hotel window overlooking the then empty spot which housed the concert event and it's not that hard to imagine the shooter's perspective, but that photo too is not really a good photo. "Mandalay" is a Myanmar/Burma city and I can't make sense of that part of the name like I can the "Bay" bit.

a reflection-based solution for drinking up records with LinqToExcel when there are not explicit column names

I'm going to have a "NoteAttribute" attribute as described here only AttributeTargets.Method will be replaced with AttributeTargets.Property as we will be dealing with the pseudogetsetters that are auto-properties in lieu of methods. I'm basically tackling this problem and keeping the logs variable as descibed only it will be a List<RowNoHeader> instead of an IQueryable<RowNoHeader> but this change like the other change is really a pretty small thing. The important thing to know is that the records we drink off of a LinqToExcel scrapping end up in the variable called logs. We use it like so:

int pseudoHeaderPosition = 8;
List<WeldLog> weldLogs = new List<WeldLog>() {};
int outerCounter = 0;
Dictionary<int, int> dictionary = new Dictionary<int, int>();
Type type = typeof(WeldLog);
PropertyInfo[] propertyInfos = type.GetProperties();
while (outerCounter < propertyInfos.Length)
{
   var metadata = propertyInfos[outerCounter].CustomAttributes.ElementAt(0)
         .ConstructorArguments[0].Value.ToString().Trim();
   int innerCounter = 0;
   while (innerCounter < logs[pseudoHeaderPosition].Count)
   {
      var pseudoHeader =
            logs[pseudoHeaderPosition][innerCounter].Value.ToString().Trim();
      if (metadata == pseudoHeader)
      {
         dictionary.Add(innerCounter,outerCounter);
      }
      innerCounter++;
   }
   outerCounter++;
}
outerCounter = pseudoHeaderPosition + 1;
while (outerCounter < logs.Count)
{
   WeldLog weldLog = new WeldLog();
   foreach (KeyValuePair<int, int> keyValuePair in dictionary)
   {
      var setting = logs[outerCounter][keyValuePair.Key].Value;
      SetIt(weldLog, propertyInfos[keyValuePair.Value], (dynamic)setting);
   }
   weldLogs.Add(weldLog);
   outerCounter++;
}

 
 

Alright, clearly (well, maybe it's not so clear) we will end up with the weldLogs variable hydrated with WeldLog records on the other side of this procedural blob and clearly WeldLog has a bunch of auto-properties on it and those auto-properties have at least one attribute each that is getting found as the first attribute for every auto-property. As you might surmise, the attribute is the NoteAttribute. The code above assumes that the 9th row of the Excel sheet contains pseudoheaders for columns (while the first 8 rows contain a fat header with various notes) and the rows after have the actual data. The WeldLog POCO looks like so:

namespace WelderConsoleApp.Logic
{
   public class WeldLog
   {
      [Note("Area")]
      public string Area { get; set; }
      
      [Note("Drawing #")]
      public string DrawingNumber { get; set; }
      
      [Note("Item #")]
      public string ItemNumber { get; set; }
      
      [Note("Weld #")]
      public string WeldNumber { get; set; }
      
      [Note("Unit")]
      public string Unit { get; set; }
   }
}

 
 

What about the SetIt method which clearly uses some dynamic magic? It looks like so:

private void SetIt(WeldLog weldLog, PropertyInfo propertyInfo, object setting)
{
   
//do nothing
}
 
private void SetIt(WeldLog weldLog, PropertyInfo propertyInfo, string setting)
{
   propertyInfo.SetValue(weldLog, setting);
}
 
private void SetIt(WeldLog weldLog, PropertyInfo propertyInfo, System.DBNull setting)
{
   
//do nothing
}

Use .DefaultIfEmpty() to make a left join with LINQ.

A left join:

public IQueryable<Feline> GetOtherCats()
{
   var q = from c in DbContext.Cats.Where(c => c.Name != "Mango")
from d in DbContext.Dogs.Where(d => d.Id == c.Enemy).DefaultIfEmpty()
select new Feline()
{
   Name = c.Name,
   RemainingNumberOfLives = c.RemainingNumberOfLives,
   Enemy = c.Enemy == null ? null : d.Name
};
   return q;
}

 
 

This is contrast is an inner join:

public IQueryable<Feline> GetOtherCats()
{
   var q = from c in DbContext.Cats.Where(c => c.Name != "Mango")
from d in DbContext.Dogs.Where(d => d.Id == c.Enemy)
select new Feline()
{
   Name = c.Name,
   RemainingNumberOfLives = c.RemainingNumberOfLives,
   Enemy = d.Name
};
   return q;
}

Monday, October 2, 2017

error TS2304: Cannot find name 'Map'.

This error and this one too...

error TS2304: Cannot find name 'Set'.

 
 

...and comparable errors about the Promise keyword will go away if you put the following in your tsconfig.json file for your Angular 4 application as a property on the compilerOptions object:

"lib": ["es5", "es6", "dom"],

 
 

This trick comes from here.

'concurrently' is not recognized as an internal or external command

Both concurrently and lite-server were missing from package.json when I got this error.