Tuesday, February 18, 2020

Git Status on Command Line Does Not Match Git Status in VSCode.

A couple of times recently I ran into a situation where VSCode was showing a lot of untracked files in git but the command line was not. Today when I opened up VSCode, it showed over 60 untracked items while the command line only showed 15. It turned out to be a simple misunderstanding on my part.

To demonstrate, I created a new git project with a new subdirectory called new-dir. Inside of new-dir, I created 3 files.

When I run git status on the command line without any parameters, it collapses new directories into single entries.

Command line example

By examining the git output in VSCode, I see now that it is running the command git status -z -u. The -z just terminates each entry in the list with a NUL instead of LF presumably for better parsing. The -u lists out each untracked file individually. And this makes sense because in the source control window of VSCode, you want to be able to see the diff of each file individually.

View of source control panel in VSCode

Wednesday, January 29, 2020

What I Learned from the Job I Didn't Get

Recently I had the unique experience of talking face-to-face with the person who beat me out for the job we both interviewed for. I want to share what I learned from this situation but first let's back up to the beginning of the story.

In 2001 I accepted a job working as NASA's Johnson Space Center as a software developer. I was equally parts shocked and excited when they offered me the job. Over the next 15 years I would have a great career working there. In May of 2016 when our contract was renewed, the government changed some things up from the previous contracts I had been on. Long story short, I ended up with a significant pay cut. It had already been 3 years since my last pay raise due to budget cuts. And with Congress at an impasse more and more, government shutdowns were becoming a regular threat. So for those reasons and others, I decided to start looking for a new job.

In July of that year, I got a call from a recruiter that had found my resume online. He told me about a frontend developer job just down the road from NASA. He got me an interview and I felt pretty good about it. Afterwards he told me that I was their first choice based on my resume and experience. However, after a few weeks went by and I heard nothing, I contacted the recruiter to get a status. He told me that they had decided to go with someone else. I was shocked, although in retrospect I shouldn't have been. I had done a terrible job of selling myself.

I also had a revelation after that: I had not dedicated enough time to professional development. In a perfect world, an employer will make professional development a priority for their employees. But we don't live in a perfect world and so the onus was on me to keep up. And I had not. Over the next couple of years I would take to Twitter, newsletters, and online training to educate myself on the latest and greatest tech in frontend development. I landed interviews with several companies during that time (sometimes even multiple interviews) but couldn't seem to get an offer. I finally decided to take a break from the job search.

About the time I made the decision to quit looking, I got a call from that company I had first interviewed with in 2016. They wanted to know if I'd be interested in interviewing for a developer job. I interviewed with some of the same people I had interviewed with before. And this time, I got an offer. I accepted the job and with much sadness, I left NASA after 17 years.

One day I realized that my coworker DJ (not his real name) was the person who had beat me out for the frontend developer position two years earlier. So I asked him about it. He told me that when he had interviewed for the job, he built a small prototype to demonstrate his skills. I really think this extra initiative on his part was what won him the job.

Lessons Learned

Professional Development

The world of web development is changing very rapidly. I had let my success at NASA stagnate me. I did look at new technologies from time to time, but I wasn't making a concerted effort to study and learn. That was a mistake. Take a little time every day out of our schedule for professional development.

Interviewing

Don't expect your resume to do all of the talking for you. I have a really hard time talking about myself. I don't like to draw attention to myself. But when you are interviewing, you have to do this. Build an online portfolio to show your work. Do something to make yourself stand out. For one job I applied for, I incorporated the company's colors and logo into my resume. The interviewer mentioned that it caught his eye.

It Will Take Some Time

When I first started interviewing, I thought it would take a few weeks maybe a couple of months at most to get an offer. I had no idea it would take two years! Be patient. Don't get your hopes up too high. Sometimes an interview will go great and you'll still get passed over for the job. That's ok. That job might have sounded great but maybe it wasn't so great. Maybe the people were difficult to work with. Maybe the management was unreasonable. Maybe the company is about to go under. Just assume that if you didn't get the job, it was for good reason.


Oh and for the record, I think hiring DJ over me was definitely the right decision. :)

Wednesday, December 4, 2019

Destructuring and Spreading in JavaScript

I wanted to get a better understanding of destructuring and spreading for a project I am working on. So I created this jsfiddle to understand it better.

What I really wanted to know was would happen if I tried to unpack a value from an object that did not exist. And then what would subsequently happen if I tried to use that value in a spread operation. For example:
const testObj = {
    a: [1, 2, 3],
    b: [4, 5, 6]
}

const { a } = testObj;
const { b } = testObj;
const { c } = testObj;

const combined = [...a, ...b, ...c];

The short answer is this: if you try to destructure a non-existent property, then you get an undefined value. And if you try to use that undefined value in a spread operation, JavaScript will throw an error: TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

Sunday, September 15, 2019

PHP: Failed opening required filepath in Unknown on line 0

I ran into this error message while working on a personal project. I had set up the code in my Microsoft OneDrive folder to sync it between my laptop and my desktop. I suspected the error might have something to do with OneDrive, so I copied my code to another folder on my computer. Sure enough, it worked perfectly. Finally, I discovered the problem. It was a setting in OneDrive called "Files On-Demand". What I suspect is that the files were simply just 0-byte stubs on my desktop. So when PHP requested them, it failed. Once I unchecked this box and OneDrive downloaded all of the necessary files, it worked just fine.

Monday, April 29, 2019

Make Your Console Statements Stand Out

Using the Chrome DevTools to debug your JavaScript code is great. Breakpoints are a great way to analyze what is going on with your code. But sometimes you just need an old-fashioned console.log. But if you have an app that is already chatty in development mode with a lot of console messages, there is a way to make your console statement stand out. You may not know that you can format your console statements with CSS. For example:
console.log('%cExample', 'background: #a00; color: #fff; font-weight: bold; font-size: 110%');
will look like this in your console:

Example

A better way to do it, though, is to use a JavaScript template literal. For example:
let xyz = 123;
console.log('%c%s', 'background: #a00; color: #fff; font-weight: bold; font-size: 110%', 
  `The value of xyz is ${xyz}`);
Will produce:

The value of xyz is 123

Now to make it even easier, we can create a VS Code snippet:
"color-console": {
 "prefix": "color-console",
 "body": [
  "console.log('%c%s', 'background: #a00; color: #fff; font-weight: bold; font-size: 110%', `$1`);"
 ],
 "description": "Color coded console message"
},
And then voilĂ 

Tuesday, April 23, 2019

Sequelize Newbie Mistake

Today I inherited a piece of code that looked something like this:
const records = Records.findOne({
    where: {
        pk: 'blah',
    },
    sort: ['dateField', 'DESC']
});
It did not seem to be sorting correctly, so I looked up ordering for Sequelize. Since I am new to Sequelize, I did not know that the correct property is order and not sort. But when I changed it, I got this error message:
Unknown column \'DESC\' in \'order clause\'
It took me longer than I care to admit to see what the issue was. If you pass an array of single items to the order property, it will use them all as part of the sort. So the backend SQL query looked something like this:
SELECT * FROM my_table WHERE pk = 'blah' ORDER BY dateField, DESC
What I really wanted was to pass it an array of arrays to sort on. So the correct code looks like this:
const records = Records.findOne({
    where: {
        pk: myValue,
    },
    order: [
        ['dateField', 'DESC']
    ],
});
Notice that order property now is an array containing an array specifying the field to sort on and the direction with which to sort it.

Thursday, March 21, 2019

Case-insensitive matching with case-sensitive replacements in JavaScript

That title is a mouth full. Here is what I was trying to accomplish: I had a search term that I wanted to highlight in a body of text. So my code needed to match all occurrences of the search term and then enclose the matched text within some HTML in order to format it. Seems simple enough, but I ran into a couple of issues.

Let's say I am going to format a phone number from a string of digits. I would do it like this:
let phone = '5551234567';
phone = phone.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
But that syntax doesn't work for me here because I need to pass the search pattern as a variable name and I need to specify the "i" and "g" flags. So this code will not work:
const searchTerm = 'xyz';
myText = myText.replace(/searchTerm/ig, 'THE'); // Not valid
First, I use the RegExp constructor to define my pattern.
const searchTerm = 'xyz';
const pattern = RegExp(searchTerm, 'ig');
let myText = 'xyz XYZ xYz';
myText = myText.replace(pattern, 
  `<span class='highlight'>${searchTerm}</span>); 
  // Results will all be lowercase because searchTerm is lowercase
Then I had to create an array of matches that I could then loop through and replace each one individually:
let sampleText = 'This is my sample text: test Test TEST';
const searchText = 'test';
const pattern = new RegExp(searchText, 'ig');
const matches = sampleText.match(pattern, sampleText);
if (matches !== null) {
 matches.forEach((match) => {
  sampleText = sampleText.replace(match, `${match}`);
 });
}
To see this in action, take a look at this JSFiddle.
 
Blogger Templates