Monday, December 18, 2017

(My Distaste for) Coding Tests

I've been interviewing for about a month and as part of that process I was recently asked to do Fizzbuzz on a whiteboard and... it did not go well. I was not initially asked to do Fizzbuzz; I was asked how I would make it testable. The conversation went something like this:

Interviewer (I): How would you make Fizzbuzz testable?
Me: All code is inherently testable so I'm not sure I understand your question.
I: The way most people solve Fizzbuzz it is not testable. How would you do it differently?
Me: If the way most people solve Fizzbuz isn't testable then they're solving it wrong because - again - all code is inherently testable.
I: OK. Solve Fizzbuzz on the whiteboard.
Me: I'm not doing Fizzbuzz.
I: *perplexed look on his face* I just want you to show me how you would make Fizzbuzz testable.
Me: OK. *starts writing for loop on whiteboard and stops* I'm not going to write out a solution to Fizzbuzz. You'd basically make it testable by assigning the value ("Fizz", "Buzz", "Fizzbuzz", or the number) to a variable, injecting a logger class, and checking whether that logger class was called with particular parameters.
I: Can you be more specific?
Me: Not really. This isn't a difficult problem so it isn't a difficult solution.

As you can see, the interview got out of hand quickly. Since that day (about two weeks ago) I've been beating myself up for how everything happened and I've come to a few realizations that I want to share.

First and foremost, asking senior software engineers to solve a "problem" like Fizzbuzz is insulting. I have samples of my code freely available on Github and would gladly have written a small application on a computer to satisfy whatever coding requirements they have. Fizzbuzz is a test that should - at best - be given to developers who just finished school to see whether they can actually code.

I'm really conflicted on whether I think they should have just not asked me or I should have just answered. Ultimately, I think it's both. They shouldn't have asked that question, but when they did, I should have answered it. It wouldn't have been difficult to just write out a solution to Fizzbuzz on the whiteboard that was unit testable. I let me ego get the best of me ("You want me to do what?!") and it ended up costing me an opportunity.

Hopefully I've learned from this mistake and I won't react the same way in the future.

Sunday, December 17, 2017

It's Not What You Say, It's What You Say

In November I got the unpleasant news that my office was going to close in 2018. On the plus side, the company gave us almost two full months' notice so we could start getting our resumes up-to-date and looking for work. I've received a couple of offers, but neither of them really felt like the right opportunity for me. One was easy to identify the issues because they were quantifiable (think money, benefits, etc.), but the other was a little trickier.

I went through the full interview process with a medium-sized publicly traded company and I liked almost everything I heard. They used the latest technologies, they had a fun atmosphere, they provided games and drinks and snacks, everybody was really cool, and so on and so on. However, multiple times in the interview they indicated that they are available to work 24/7. The recruiter tried to clarify that they work a pretty standard schedule, but the gut feeling I had remained and I couldn't shake it.

This interview process revealed to me that it's not necessarily what you say, but it's also what you say. What I mean is that during the interview process they told me - I felt in no uncertain terms - that I would need to live and breathe the company if I came on board. That's fine for some people, but that's now what I'm about so it wouldn't have worked for me. Even though they tried to clear it up, even their clarification continued to tell me what I had previously heard.

Ultimately, I might be missing out on a great opportunity, and that would suck. But I'd rather miss out on a company than ignore my gut instinct that says this isn't the right place for me.

Update: I've had a few friends go to work for this company and my suspicions were correct. On top of the 24/7 availability, they have few to no processes (which is a big problem for me). I can confidently say 5 years later that declining this offer was the right move for me.

Tuesday, November 21, 2017

JavaScript Array.Filter

Several times in the recent past I've had a need to grab certain objects from an array based on a value of one of their properties. In Linq in C# I'd do something like this:
filteredItems = allItems.Where(i => i.FirstName == "Mickey");

In TypeScript I don't have Linq functions so I need an alternative when I'm writing Angular. Fortunately, JavaScript includes the Array.prototype.filter function that works very similarly. When I want to do the exact same thing as above, but in JavaScript (and therefore in TypeScripe) I'd do this:
filteredItems = allItems.filter(i => i.FirstName === "Mickey");

Did I say they were similar? Because they're pretty much identical. I'm sure I'll be revisiting this post many times in the future.

Saturday, November 11, 2017

All About Interfaces

I was recently asked for some good reading material on the difference between implementing and injecting interfaces and I couldn't come up with anything. I know the root cause of the lack of material is that the two concepts are totally different, but they are related so it's worth discussing them together.

First let's look at what an interface is in object-oriented programming. The simplest way to think of interfaces is as contracts. If you hire a crew to paint your house you're going to sign a contract with them. You've defined in the contract exactly which parts of the house need to be painted, the color of the paint in each area, and perhaps some small improvements to be done as they paint. When the painter agrees to take on the job, he's agreeing to implement that contract exactly as you specified.

An interface in programming is exactly the same as the contract we had the painter agree to. If we define an interface we're saying that any classes that want to agree to (implement) that interface must be structured exactly as the interface specifies. Let's take our painting example virtual and define our contract as an interface.
   1:  public interface IBindPainters
   2:  {
   3:      List<Improvement> Improvements { get; set; }
   4:  
   5:      Dictionary<Location, Color> Colors { get; set; }
   6:  
   7:      void Improve(Improvement improvement);
   8:  
   9:      void Paint(House house);
   10:  }

Any painter classes we create that want to implement (agree to) this interface (contract) must have a property called Improvements, a property called Colors, and methods called Improve and Paint. The signatures of the methods and types of the properties must also match the interface. So if we create a class called JohnPainter that wants to implement this interface it would at least look like what you see below.
   1:  public class JohnPainter : IBindPainters
   2:  {
   3:      public List<Improvement> Improvements { get; set; }
   4:  
   5:      public Dictionary<Location, Color> Colors { get; set; }
   6:  
   7:      public void Improve(Improvement improvement)
   8:      {
   9:          // do improvements around the house
   10:     }
   11:  
   12:     public void Paint(House house)
   13:     {
   14:         // paint the house
   15:     }
   16:  }

If we create a class called FrankPainter that wants to implement this interface, it would at least look like what you see below.
   1:  public class FrankPainter : IBindPainters
   2:  {
   3:      public List<Improvement> Improvements { get; set; }
   4:  
   5:      public Dictionary<Location, Color> Colors { get; set; }
   6:  
   7:      public void Improve(Improvement improvement)
   8:      {
   9:          // do improvements around the house
   10:     }
   11:  
   12:     public void Paint(House house)
   13:     {
   14:         // paint the house
   15:     }
   16:  }

Both of those classes implement the interface, which means that both John and Frank have agreed to our contract. That's literally all interfaces are for! An interface doesn't specify how the work gets done - Frank and John might each paint that house using completely different processes - and it doesn't actually do anything. It just guarantees that whoever implements the contract agrees to the terms.

So the next question that usually comes up is Why? Why do we use interfaces at all? Well, let's keep moving forward with the house painting example we've been using and see if we can answer that question, too.

As the homeowner, I know how the process of having my house painted is going to work. I'm going to hire a painter, give them the colors to paint each part of the house, show them the improvements that need to be made, have them do the improvements, then paint the house, then I'll pay them. Before I hire the painter, I can define my entire process, like this:
   1:  public class HomeOwner
   2:  {
   3:      private IBindPainters _hiredPainter;
   4:      private House _house;
   5:  
   6:      public HomeOwner(IBindPainters hiredPainter)
   7:      {
   8:          _hiredPainter = hiredPainter;
   9:         _house = new House();
   10:     }
   11:  
   12:     public void HaveHousePainted()
   13:     {
   14:         _hiredPainter.Colors = new Dictionary<Location, Color>();
   15:         _hiredPainter.Improvements = new List<Improvement>();
   16:         foreach (var improvement in _hiredPainter.Improvements)
   17:         {
   18:             _hiredPainter.Improve(improvement);
   19:         }
   20:  
   21:         _hiredPainter.Paint(this._house);
   22:     }
   23:  }

So what does this do for us? Well, we know that whatever painter we hire they're going to have to agree to our contract, so we can setup our entire day before we know who is going to actually paint the house. If we decide to hire Frank we just pass Frank as the painter into our constructor and everything works fine. If we decide to hire John we just pass John as the painter into our constructor and everything works fine.

Since our constructor is expecting an interface (IBindPainters) what it's really expecting is a class that implements that interface. Whether that class is John or Frank makes no difference to how we're going to have our house painter. Whoever we hire is going to have to agree to our contract.

This really comes in handy when we don't know ahead of time which class we'll get. Let's say I'm not the one picking the painter; it's my wife instead, but she can't be home when the painter shows up. She leaves me very clear instructions on what to do when the painter gets there (give him the colors and areas to paint those colors, show him the improvements, have him make the improvements, then have him paint), but she forgets to tell me who she hired. Well, it doesn't matter as long as the person who shows up agrees to the contract.

When the painter shows up - whoever it is - we just plug him into our predefined process and he gets to work. Guess what? That's what injecting an interface means! Injecting an interface just means we provide a class that implements the interface, but we depend on (expect) the interface instead of a specific class.

Let's recap.

  • An interface is just a contract; it cannot be instantiated itself
  • When a class implements an interface, it just means that class agrees to the terms of the contract
  • Injecting an interface means we expect a class that implements an interface to be provided
  • Interfaces do not actually do anything... ever!
Hopefully this helps you out if you've been trying to understand interfaces and/or injecting them.

Thursday, July 20, 2017

Unit Testing Web API when the Result is an Anonymous Object

Sometimes it seems like each day opens my eyes to some new challenge or trick.  If only I could find the time to write about them all.  Today I discovered you can return anonymous objects from a WebAPI controller.  Returning the data was actually the easy part, but being able to unit test it turned out to be a little bit tricky.

I found this answer on Stack Overflow, which pointed to this blog post by Patrick Desjardins that ultimately helped me figure out what needed to be done, but I wanted to document the actual steps I took to make this all work.

The scenario was that we had a custom object that had a bunch of properties on it.  Our UI needed all of that information plus one more field, but we weren't able to just add another property to our object because reasons (that part isn't important).  We also didn't want to create a brand new object to contain our original object plus this other field.  The obvious solution was to return an anonymous type from our controller.

Let's say our object is book and it has a couple of properties on it.  It looks like this:

   1:  public class Book
   2:  {
   3:      public string Author { get; set; }
   4:          
   5:      public string ISBN { get; set; }
   6:  }

When we return our object to the UI we also need to include a StoreId.  What we want to return will look like this:
{
  StoreId: 12345,
  Book: {
    Author: "Herman Melville"
        
    ISBN: "978-1853260087"
  }
}

What we ended up with was a controller method that looks like this:
   1:  [HttpGet]
   2:  public async Task<IHttpActionResult> GetBook()
   3:  {
   4:      var book = new Book
   5:      {
   6:          Author = "Herman Melville",
   7:          ISBN = "978-1853260087"
   8:      };
   9:   
  10:      var result = new {StoreId = 12345, Book = book};
  11:      return Ok(result);
  12:  }

In order to test this we have to do two things.  For starters let's say our Web API project is called Bookstore.Api and our unit tests are in a separate project called Bookstore.Api.UnitTests.  We need to modify the AssemblyInfo.cs file in Bookstore.Api to make internal types available to Bookstore.Api.UnitTests because the anonymous object we're returning from the GetBook method becomes an internal type when it's created.  To do this, just open AssemblyInfo.cs in Bookstore.Api and add this line (where it gets added doesn't seem to matter, but the name absolutely does matter):
[assembly: InternalsVisibleTo("Bookstore.Api.UnitTests")]

Important Note: In .Net Core 2.0 (at least) you have to create the AssemblyInfo.cs file manually as it is no longer generated automatically when you create the file. I just expanded the Properties folder, right-clicked > Add > Class > AssemblyInfo.cs and added the above attribute as the only thing in the file. I did have to include the using statement for System.Runtime.CompilerServices as well.

Finally we can write our test to check the return value of the StoreId in our unit test:
   1:  [TestMethod]
   2:  public async Task GetBookShouldReturnStoreIdWithBook()
   3:  {
   4:      dynamic result = await bookController.GetBook();
   5:   
   6:      Assert.AreEqual(12345, result.Content.StoreId);
   7:  }

It's really important to use dynamic as the return type (as much as I hate doing that) because it's the only way the compiler won't make angry faces at you.  I hope this helps someone (or future me).

Monday, May 15, 2017

Microsoft Build 2017 - Part 1

I know I've been spending a lot of time talking about Angular 2 (or 4) lately, but last week I was afforded the opportunity to attend Microsoft's annual Build conference in Seattle and, boy was I impressed.  I want to take a few posts to tell the world (and remind myself) about all the cool stuff I saw.  And since this is my blog I'm going to do just that.

So let me start with the Day 1 Keynote.  Yes, it was 3-ish hours long and there was a lot that I felt could have been cut out, but there was a ton of information they put out there that blew me away.  I seriously watched parts of the keynote with my mouth hanging open.  It was embarrassing.  So what was so cool?  Well, let's start with the Azure Stack because I've been in situations where this particular technology would have solved issues that we weren't able to solve at the time.

Azure Stack

Azure Stack is all the stuff we know and love in Azure, but deployed to other servers.  I remember a couple of years ago I was interviewing for a senior developer role with a company that was all excited about switching to Azure because they "could deploy it wherever they wanted".  I didn't take that job primarily because of that fundamental misunderstanding of what Azure iswas.  If Azure Stack had been available then I'd have been laughed out of the room for explaining to the Director of IT that what he had described was impossible... and also that company would probably still be in business.  At any rate, there are a variety of reasons that companies have avoided switching to cloud-based solutions and Azure Stack solves a few of them.  The examples provided in the keynote all had to do with remote-based workers and non-connected branches (like cruise ships), but the first thing that came to my mind were government organizations.  On at least two occasions I've had first hand experience with government agencies being unable to use Azure in particular because of legal restrictions on where their data can be housed.  They had to be able to show at any given moment that all of their information was stored in a particular state or country.  With Azure Stack they'd be able to do that because they'd be managing the physical servers running Azure!  This is an incredible option now!

Furthermore, SaaS companies using Azure (like my current employer) this opens up a whole new area of opportunities.  We can now sell our products to companies that are unwilling or unable to shift to a cloud-hosted solution like Azure.  We can write our code once and use it in the cloud as well as make it available for those offline solutions.

Outside of the keynote I also checked in with the Azure Stack booth and confirmed that Azure Stack is literally all of the functionality of Azure, but portable to any data center or proprietary servers.  I also asked for confirmation that Azure Stack customers would be able to - but not forced - to update when a new version of the software is released, and that was confirmed.  That means that late adopters of SaaS products can exist if they use Azure Stack.  SO COOL!  (Yeah, I'm gonna nerd out on most of this stuff so just get used to it now.)

Azure IoT Edge

OK, I have to admit that while I thought the MS demo for this was pretty neat, I didn't immediately see a benefit of using it on anything I worked on.  From what I understand - and this is mostly based on the demo they showed - this basically allows us to offload some processing from the cloud to individual IoT devices.  That is pretty darn cool, especially when you're talking about latency potentially costing money.  If you have a device - and endpoint - that needs some telemetry to know when to change things (maybe slow down or speed up production based on something else happening down the line) you can export that telemetry to the device itself and save the latency.  In the case of the demo this potentially led to millions of dollars in savings if a machine shuts itself down before something goes terribly wrong.  Pretty cool stuff, but again I didn't see any immediate application for anything I'm working on.

Azure Browser CLI

This one was cool for an obvious reason, and a not-so-obvious reason.  First the obvious reason: DUDE, THEY PUT AN AZURE CLI IN THE FREAKIN' BROWSER!  C'MON, THAT'S AWESOME!  OK, so what that means is that now anyone who is more comfortable scripting their commands than using the Azure Portal can now use the CLI in the browser itself.  There's nothing to install and nothing to add; it's already live and it already works.  Very cool for keyboard jockeys like me.

OK, so the not-so-obvious reason: they did it in bash... from Linux.  And what's more is they said during the presentation that basically "we'll get to doing it in Powershell eventually".  That's HUGE.  All my life Microsoft has taken the stance of "Windows first, second, and forever" and everything else can go suck a lemon.  When they have ported some stuff to other platforms in the past it's always been 1) a port, and 2) usually missing some features.  This time around they basically said "Linux does this pretty well so we're gonna start there and if the Powershell team decides they want to implement a Powershell version they can later".  That is simply an amazing turnaround and I could not possibly love it more.

Azure Portal Mobile App

This was another one that I didn't see an immediate use for, but I know several of the guys (sadly, yes, all guys because we do have a gender issue in technology) around me got very excited when this came up.  The app brings the Azure Portal to our devices so we can... do Azure Portal stuff on the go, I guess?  I can see this being useful if you're in DevOps and\or you're administering things from the portal frequently.  In my day-to-day I don't need to do this so while I see that it is cool, it really isn't that cool for me.

Visual Studio for Mac

I won't lie to you. I am 100% not excited about this one.  I mean, don't get me wrong, I know some Mac people and they're pretty OK.  My wife was a Mac person before I converted her.  But I don't know any developers who prefer Visual Studio who also prefer Macs.  I'm sure they exist, but I don't know any.  And I'm not one (I just don't care for Mac's OSs).  So it's not that this isn't exciting, it just isn't exciting for me.

I will say that I heard some pretty bad reviews from people who used the beta version of this so even if I was a Mac person I'm not sure I'd be too thrilled about this.

PowerPoint Translator

I don't think this feature got enough love in the keynote because frankly it's amazing.  As a side job I used to teach adults how to use computers.  I taught them everything from what a computer is through using Access.  I speak English and Spanish, but I still couldn't reach all of my students.  If I'd had PowerPoint Translator back then I could have reached more people.  Not many more, but more.  I've also talked to some friends of mine who are trainers in similar areas and they are very excited about this technology.

Just having the ability to provide closed captioning in another language as you speak is... well, it's amazing is what it is.  It's not the Universal Translator from Star Trek, but holy cow it's a huge step in the right direction.  I know we have things like Google Translate and Facebook has a translation feature, but this puts all of the power of a translation service directly into PowerPoint presentations with very little additional work - and no technical know-how - from the trainer.  I know there are corporate applications as well, but the first thing that struck me was the ability to reach more people with important information, like training immigrants how to use computers to find work.

Cortana

When I told my brother about all the cool stuff they were showing with regards to Cortana he said "Cortana needs to die". I tried to convince him that what I was seeing was really cool, but he didn't want to hear it.  I hope he comes around and at least looks into it because it really is really cool.  What do I mean?  I'm glad you asked!

Let me start by asking you this: did you know Cortana was available on iOS and Android devices?  You did?  Well... way to steal my thunder then... jerk.  I didn't.  Right off the bat, that's pretty cool.  I know iOS has Siri and Android has... whatever you call it when you say "OK, Google" and it does stuff, so this is just one more voice-activated AI-ish type deal you can have on your phone.  However, with Cortana on your devices you can actually integrate all of your stuff better.  And you can create new "skills" (yeah, I think it's a stupid term for it, too) for Cortana to learn to do stuff for you.  So let's say your company produces a SaaS for finding picnic baskets in Jellystone Park.  You can write a bot (more on that later, maybe not in this post, but definitely later) that then interacts with a Cortana skill so you can have users say to their phone "Cortana, ask Yogi where to find the closest picnic basket".  And with that, Cortana can check with your bot and return information however you deem most appropriate.  The demo from the keynote is pretty cool, but I don't think they did a good job of separating Microsoft Teams (which I think is also new, but I wasn't entirely sure) from Cortana's capabilities.  They also didn't do a great job differentiating between the bot and the Cortana skill so I had to do some more digging.

At the Cortana Skills booth is where I learned about bots and a little bit more about skills.  Basically the bot does the heavy lifting and can be integrated into lots of different channels besides Cortana.  But Cortana gets to do some of the fun stuff when you write a skill.  The booth guy was helpful, but ultimately it sounded like I needed to learn more about bots.  Then I went to the Cortana Skills presentation on day 2 and got even more information.  I hope that presentation gets posted to Channel 9 because it was actually really helpful to watch a developer write a skill and deploy it.  He showed us in the demo how we can change Cortana's output to include things like a card in the search results (similar to what Bing does right now if you search for something).  Cortana isn't just voice activated, but it is intended to be primarily voice activated so you have to consider that as well.  All-in-all I saw some pretty neat applications for some things I'm working on now and in the near future.

OK, this post has gotten a bit out of hand.  I'm not even through the whole keynote yet and I feel like I've written a novel.  I'm gonna wrap this one up here and try to add another one tomorrow.  I have a lot more to cover and some of the really cool stuff is yet to come, not to mention the fact that I haven't even touched on the Day 2 Keynote.  Man, it was a packed 3 days.

Tuesday, April 25, 2017

Angular 2 - External Libraries

This is the fifth in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  Previous installments in the series can be found here, here, here, and here.  I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first four installments you can get the code that was generated during the fourth installment by visiting Github (here) and switching to the routing-part-deux branch.

In this installment we're going to learn how to use external libraries, and some pitfalls to watch out for when you do it.  We've got a lot of functionality, but our website looks... well, bad.  Let's use Bootstrap to make it look better.  I'll go ahead and tell you right now that I'm not a design expert so even when we're completely finished here our site might not look very "good", but it will look better than it does right now.

The first thing we need to do is get bootstrap.  As of this writing Bootstrap 4 is in alpha, but I like what they're doing with it so that's actually what I'm going to use.  It doesn't matter, though.  The point of this post is to show you how to use any third party library, not specifically Bootstrap.  Assuming the library you want to use has an npm package you'd go ahead and install the package at the root level of your module (D:\Dev\Learning\Angular2\Cli\ProveIt).  I'm running npm install bootstrap@4.0.0-alpha.6 --save, which will install that specific version of Bootstrap and save it as a dependency.  This also installs Boostrap's dependencies (jQuery and tether) so we're all good to start using it now.

Now that we've got it installed we need to include the appropriate references in our project.  In a pure JavaScript application we'd just add a <script> tag to our index.html and we'd be all set, but that's not how we do things with the Angular CLI.  We need to add a reference to the bootstrap css that's now in our node_modules folder.  Open your .angular-cli.json file and add the relative path reference to bootstrap's css (or sass or scss) file to the styles array.  The styles array should be around line 21 and should currently contain a single value: styles.scss (remember we modified this array in the first installment of this series, too).  My relative reference is "../node_modules/bootstrap/scss/bootstrap.scss".  As soon as you've added that, serve the application and you should immediately see that your links are styled slightly differently.

That's all well and fine if the external library has an npm package, but what if it doesn't?  That's easy enough, too.  For the sake of demonstration let's say you want to use a custom build of Bootstrap, which is a common enough scenario.  So you go to getbootstrap.com and build your customized version, which includes CSS and JavaScript files you need to include.  You unzip them and save the minified files... where?  I like to create a vendor directory in my Angular CLI project directory so I'd save my files in D:\Dev\Learning\Angular2\cli\ProveIt\src\vendor\bootstrap.  Once the files are in a directory I can reference I need to add them to my .angular-cli.json file the same as I did before.  This time I also have a .js file I want to reference so I also need to modify the scripts array, which is just after the styles array in the same .json file.  My references are "./vendor/bootstrap/bootstrap.min.css" and "./vendor/bootstrap/bootstrap.min.js".  I removed my other bootstrap reference just to be sure everything is working as desired and when I serve my app again it looks good.

As far as I can tell, the CLI will respect import order so if you have conflicting styles in some stylesheets, the last styles imported will be used.

Right now I'm getting an error in my console that says that "Bootstrap's JavaScript requires jQuery at eval", which tells me I forgot to include jQuery in my scripts array.  I'll just add the reference to it from my node_modules folder and I'll be all set.

I'm going to do a little bit of styling, but I'm not going to describe it here.  I'm basically just going to move things towards the center of the page, use a jumbotron and list item styling to make my students page look better.  You can do your own or view my completed code on Github (the link is below).

There's another way to reference external libraries for consumption within an Angular project, but I'm not going to cover that quite yet.  It will probably be the topic of the next installment of this guide.  For now, the final code from this module can be found on Github (here).  Switch to the external-libraries branch.

Wednesday, April 19, 2017

Angular 2 - Routing Part Deux

This is the fourth in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  Previous installments in the series can be found here, here, and here.  I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first three installments you can get the code that was generated during the third installment by visiting Github (here) and switching to the routing branch.

In this installment we're going to continue learning about routing and finish up the routing we started in the last installment.  Right now we have an application that has routes configured to view all students and one individual student (by id) as well as a redirect route from our root URL and a route for when the page is not found.  That's great and everything, but we're missing a couple of key pieces.  First, our individual student page just doesn't work.  If we navigate to /student/1 (or any number for that matter) we get a blank page and if we check our console we see a bunch of errors, so what gives?  Well, our individual student component (StudentComponent) isn't designed to work with our individual student route (/student/1).  Our StudentComponent has an input property of student, but when we navigate directly to the StudentComponent via the router, there is nothing input so our template parsing fails.  We can fix it pretty easily, though, so let's do it.

First we'll create a service in the common folder.  The command for a service is ng g service studnet. Make sure to run this command from inside the common folder (D:\Dev\Learning\Angular2\cli\ProveIt\src\app\common) so that your service files get created in the right location. Unlike when it creates a component, when the CLI generates a service it does not generate a new folder for the service. Since we want it in common we need to be in common when we run the command. We want to move the students array out of the StudentsComponent and into this service so the array can be shared between components more easily. You can just copy/paste the entire students array directly from students.component.ts to student.service.ts. Once we've done that we need to import the service in the StudentsComponent, inject the service into the component through the constructor, and initialize the students array of the component so it can be displayed to the user. Here's what my students.component.ts file looks like after I do all of that:
import { Component, OnInit } from '@angular/core'; import { Student } from '../common/student'; import { StudentService } from '../common/student.service'; @Component({   selector: 'app-students',   templateUrl: './students.component.html',   styleUrls: ['./students.component.css'] }) export class StudentsComponent implements OnInit {   selectedStudent: Student;   students: Student[];   constructor(private studentService: StudentService) { }   ngOnInit() {     this.students = this.studentService.students;   }   show(student) {     this.selectedStudent = student;   } }

I want to take a quick moment to discuss the constructor up there. What you see in there is actually a shortcut to create a private variable called studentService that is of type StudentService, and also assign the StudentService provider to the studentService variable. That constructor code allows us to assign the students property that's in the StudentService to the students variable in the StudentsComponent, which we do in the ngOnInit function. The next change we need to make is actually at the module level. We need to add the new StudentService as a provider to the entire module. To do that, import StudentService in app.module.ts, then add StudentService to the providers array (it will be the only item in the array after you add it).

Now that we have our students all stored in a service we can add the piece that we need to fix the StudentComponent.  In student.component.ts we have an ngOnInit method and that's where we want to get the student whose id matches the id passed in the URL.  The first thing we need to do to facilitate that lookup is import the StudentService in this component and inject it in the constructor.  That code is identical to what we did in the StudentsComponent so I won't repeat it here.

Next we want to change the ngOnInit function to get a single student.  Since we're doing this in small steps, let's just get the first student from the students array and use it.  To do that we'll be setting this.student to the first element of the students array on the StudentService, like this:this.student = this.studentService.students[0];

Now if you navigate to /student/1 you should see the details of the student with id 1.  Huzzah!  But that's not really what we want because if you navigate to /student/2 you'll still see the details of the student with id 1.  So we need to wire up our URL to our lookup the correct student based on which id was passed.  To do that we actually need to bring a couple more pieces into our StudentComponent: ActivatedRoute and Params from @angular/router, and we want to import switchMap, Observable, and observable.of from rxjs.  Here are the imports you'll want:
import { Observable } from 'rxjs/Observable'; import { ActivatedRoute, Params } from '@angular/router'; import 'rxjs/add/operator/switchMap'; import 'rxjs/add/observable/of';

Next, we need to modify the constructor to inject the ActivatedRoute and set it to a private variable called activatedRoute (again, you can call it whatever you want, but in my code that's the name I used).

Now we want to use them in our ngOnInit function:
this.activatedRoute.params.switchMap((params: Params) => {   const internalStudent = this.studentService.students.find((student) => {     return student.id === +params['id'];   });   return Observable.of(internalStudent); }).subscribe(student => this.student = student);
Now if you navigate to /student/2 you see the details for the student with id 2.  Huzzah!  So what's that code actually doing?  I'm glad you asked!

The activated route provides information on the current route (the current "page") and the .params property of the activated route provides us the parameters that came in from the route.  switchMap is an rxjs function that cancels previous calls to the same route with different parameters.  That way if we go to /student/1, but then - before the route is finished - we change it to /student/2, the first call is cancelled and any calls to a remote API are cancelled as well.  This prevents the problem of getting the result of the first call back from a long running process after you get the results of the second call (since those calls would be asynchronous).  Inside switchMap we have a callback function that looks up a student based on their id.  The + in on the params['id'] check converts the parameter value to a number so the lookup is successful.  We're using Observable.of (another rxjs capability) to return an observable as the result of the switchMap function so we can subscribe to the observable.  Observables and subscriptions are an advanced topic (that I don't fully understand yet) that I'll cover in a future installment of this guide.  For now, just accept it.  Our .subscribe function assigns the result of the switchMap (I think) to the student property of the component.

The very last thing we need to do is change our StudentsComponent to take the user to the student detail page when the user clicks on one of the students.  Right now when they click we show the details on the bottom of the page so we want to remove that and replace the click function of our div to an anchor tag that is a routerLink.  Here's the updated markup from students.component.html:

<div *ngFor="let student of students">   <a [routerLink]="['/student/' + student.id]">{{student.id}} {{student.name}} {{student.teacherId}} {{student.age}}</a> </div>


This is pretty straightforward once you know about the [routerLink] directive.  We're still iterating through all of the students and displaying their info, but now we're doing it inside an anchor tag that applies the [routerLink] directive.  We're appending the current student's ID to the /student/ route and voila!  We have a working app.  Of course there are still quite a few mysterious parts that we'll need to clear up, but we'll get there.

The final code from this module can be found on Github (here).  Switch to the routing-part-deux branch.

Tuesday, April 18, 2017

Angular 2 - Routing

This is the third in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  The first installment in the series can be found here, and the second can be found here.   I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first two installments you can get the code that was generated during those parts of the guide by visiting Github (here) and switching to the second-installment branch.

In this installment we're going to learn about routing.  Routing is the method we use to show different content depending on the URL the user has visited.  Routing enables us to load the majority of our resources and content once time and then inject different content whenever the user changes the route (by clicking a link, a button, changing the URL in the address bar, or some other method).  If you're still a little bit confused try to imagine a childrens toy called the View Master.  It's a set of lenses that the child can look through to see a picture.  When they click a button the picture changes.
The child doesn't have to change the entire View Master to look at a different picture, he just flicks the tab and a new picture appears for him.  Routing works the same way.  The overall structure of the page and the resources stay right where they are (this is the View Master part) and the content that is injected changes when the user clicks a button (this is the picture wheel the View Master uses).

Routing has been around for a while and Angular JS (aka Angular 1.x) had sort of a love/hate relationship with routing.  I know that I tended not to use the built-in routing in Angular 2, favoring the more robust (at the time, at least) ng-router.  In Angular 2, though, the team decided to make things easier and incorporate them a bit more.  Since the whole framework is more modular anyway it worked out quite nicely to have routing in a separate module that can be used... or not.  On a side note, the reason the team jumped over Angular 3 and went straight from 2 to 4 was they wanted to keep the version number of Angular in sync with the version number of the router.  Not pertinent in any way, but it seems like something useful to know.

Since adding routing is so easy let's just get started.  Create a new file as a sibling of app.module.ts (so mine will be created at D:\Dev\Learning\Angular2\cli\ProveIt\src\app) named routes.ts (the name doesn't matter so if you don't like routes.ts name it whatever you want).

The first thing we need to do in our new file is import Routes from @angular/router:import { Routes } from '@angular/router';

Now we need to import the components we'll use in our routes.  When someone visits http://www.mysite.com/students we want them to see our StudentsComponent, but if they visit http://www.mysite.com/student/1 we want them to see our StudentComponent for the student with id 1.  To do this we'll need to import both components in our routes.ts file.  You should know how to do that by now so I'm not going to show you.

Let's set up the routes to do what we just described.  Create and export a constant named appRoutes that is of type Routes:
export const appRoutesRoutes = [];

Now that we have our constant defined it's just a matter of adding the routes that we want.  Each route object can have a path and a component property. Create the routes (inside the appRoutes array):
path: 'students'component: StudentsComponent }, { path: 'student/:id'component: StudentComponent },

Now that we have our route constant created we need to wire it up to our module so go to your app.module.ts file and import the appRoutes constant from the routes file:import { appRoutes } from './routes'. Now we need to import RouterModule from @angular/router and use it to bring in our appRoutes constant. I'll leave the import statement to you, but here's how you'd use it (in the imports array in your @NgModule recipe):RouterModule.forRoot(appRoutes),

The last thing we need to do is change our app.component.html to use the router instead of loading our StudentsComponent directly.  We do that by modifying the html to be: <router-outlet></router-outlet>. If you're running your app you'll probably notice that now all you see is a blank screen. That's because the app is navigating to the root ("/") and we haven't configured that route. Change the URL to have /students on the end and you should see your students component.

We can actually configure the root route to redirect to our students route pretty easily so we'll go ahead and do that now.  Back in routes.ts add one more route to the list, but this one won't have a component property, it'll have a redirectTo property.  Like this:path: ''redirectTo: 'students'pathMatch: 'full' }.  With just this last change we can navigate to our root URL and be redirect to our students list (it even updates the URL in the address bar for us!).

OK, that wasn't the last thing.  We have one more optional item.  We can add a PageNotFoundComponent and redirect all other routes to go there instead of throwing an error.  The only piece of information I haven't given you to do that on your own is that the path of the route you'd want to create is **.  My final version is checked in on Github, on the routing branch.  We have a bit more to cover with routing, but this post is getting long so I'm going to end here and pick up the rest in another installment.

Friday, April 14, 2017

Angular 2 - Our First Component

This is the second in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  The first installment in the series can be found here.  I'm going to build on what I did in that post so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip that first installment you can get the code that we generated during that part of the guide by visiting Github (here) and switching to the first-installment branch.

At this point we have our basic application running and we essentially have "Hello, World" going in our browser.  That's a great start, but it doesn't really do anything for us.  Let's build out the application by displaying a list of students in the UI.  We're not going to worry about styling right now.  Instead we're just going to show each student in a separate div.  We can style it later (or not, whatever).

Let's take an object-oriented approach to this part (I know, "object-oriented approach to JavaScript?!?!", but yes.  We're using TypeScript and the newer versions of the ECMAScript specification support designing objects).  What is a student?  For our purposes we're going to say a student has the following characteristics:

  • id
  • name
  • teacherId
  • age
If we were writing in C# we'd create a POCO that represents a single student and specify somewhere that we have a List<Student>.  Since this is TypeScript we're going to do things slightly differently.  Create a new folder under src/app and name it "common" (obviously without the quotes).  In your command prompt, navigate to that new folder (so I navigated to D:\Dev\Learning\Angular2\cli\ProveIt\src\app\common) and run the command ng g interface student. This creates a new interface called student in the common folder.  Go ahead and open that file (src/app/common/student.ts) and you'll see that it's pretty simple at this point.  It's just a declaration and export of what amounts to a POCO - or in this case a POJSO (Plain Old JavaScript Object).

We can add our properties to the interface and specify their type.  Our new interface looks like this:
export interface Student {     idnumber;     namestring;     teacherIdnumber;     agenumber; }
All we've done here is specify what a Student looks like to us.  Now we're going to use our Student interface in our StudentsComponent.  Open src/app/students/students.component.ts and import the new Student interface at the top of the file.
import { Student } from'../common/student';
Now that we have our Student interface available to us, we'll create a property on our StudentComponent that is an array of Students.  Just inside the creation of the StudentComponent class (so this would be above the constructor) add this line: studentsStudent[] = [];. This tells Angular that our every single object in our students array is going to implement the Student interface. Doing this gives us type checking while we develop. In Angular! How cool is that!?

Go ahead and populate the students array with 5 students.  Just make up the information.  I usually use pop culture characters and consecutive numbers for ids.

If you're not already serving your application you should do that now and make sure everything still works properly.  In your command prompt navigate to the application directory (so mine is D:\Dev\Learning\Angular2\cli\ProveIt) and run the ng serve --open command.  You should still see "students works!" as the only thing on the page.  We're about to change that.

Open your students.component.html file and replace the contents of the file with this:
<div *ngFor="let student of students">   {{student.id}} {{student.name}} {{student.teacherId}} {{student.age}} </div>
If you look at your application now you'll see each student's information listed on a separate line. Sweet! That's what we were going for. Remember that at least for now we don't really care how it looks. In a future installment of this guide we're going to bring in Bootstrap and style this up a little bit better. For now we have a little bit more work to do.

Let's create another component; one that allows us to view the details of a student.  Right now we only have a little bit of information about them, but we want to be able to see more.  To create a new component we'll use Angular CLI from the command prompt.  Go to src/app and run the command ng g component student to create a new StudentComponent.  If you're worried that the name will be too easy to confuse with the current StudentsComponent you can name it something else (like student-detail) if you want.

Open the newly created student.component.ts and we're going to jump right in to making some changes.  Right away we want to import Input from @angular/core so you can just add it after the import of OnInit (in the same curly brace).  We also want to import the Student interface like we did in the StudentsComponent.  In fact, you can copy that line exactly from StudentsComponent into StudentComponent.  Next we'll add an input property called student.  Add this line just above the constructor: @Input() studentStudent;  Setting the @Input() decorator on this property tells Angular that we're going to get this value as an input wherever the StudentComponent is used.  Add city (as a string) to the Student interface, then update the list of students so that each student has a city.

In student.component.ts replace the templateUrl with an inline template by replacing the entire templateUrl line with this: template'<p>{{student.name}} lives in {{student.city}}</p> So now all we need to do is figure out which student's information to show and how to show it.  We're going to go back to students.component.html and make a few changes now.  Oh, you can delete student.component.html if you want to since we're not using it anymore.

Back in students.component.html we're going to add a click handler on the main div that's repeating for each student.  When the user clicks on a student in the list of students we're going to invoke a function called show and pass the current student to that function: (click)="show(student)" You'll want to add that to the <div> that has the *ngFor on it. Down below that <div> we're going to introduce the student component by adding this code:
<app-student *ngIf="selectedStudent" [student]="selectedStudent"></app-student>
Now we'll wire up that click event to set the selectedStudent to whatever student was passed to the function. First we need to add a property called selectedStudent that is of type Student. You should know how to do this by now so I'm not going to show you.
show(student) { this.selectedStudent = student; }
So now we have (sort of) a working app. We can see a list of students and we can click on a student to view his "details" (such as they are). We have two components working together and we have an interface keeping us honest with our Student objects. We've taken an object-oriented approach to creating an Angular 2 application and so far it's going pretty well. We'll look at routing in our application in the next installment, btu that's all for now.

Angular 2 - Getting Started with Angular CLI

Angular 2 (finally) went live in September 2016 and I (finally) have had a chance to work on it, both at work and on a couple of personal projects.  This post is a bit of a deviation from the overall intention of my blog in that there are already some pretty good guides available for getting started with Angular 2.  The only reason I'm writing this one is to make sure I understand the ins and outs of doing it myself.  So, I guess in that regard, this post isn't a deviation at all.  Huh.  Cool.

I'll start off by pointing out that, yes, Angular 4 is already released (don't worry they just skipped 3).  I plan to work with 4 soon enough, but so far what I've done has been in 2 so that's what I'm documenting.  Since 4 is already out it can be a bit tricky to find the documentation for 2, so here's a link to it: https://v2.angular.io/docs/ts/latest/.  Now that that's out of the way, let's dig right in.

OK, so you'll still need npm (and therefore node.js) installed so if you haven't done that yet, do it now.  With npm installed you can install the Angular CLI globally with the following command: npm install @angular/cli -g.  All of the CLI documentation can be found here.

I've checked in the code that corresponds to this series on Github.  You can find it here.  For this installment of this guide you'll want to checkout the first-installment branch.

Once the CLI is installed you just have to run the following command in the directory you want to create your project: ng new [project name] where [project name] is the name of your project. So I'm going to create a project at D:\Dev\Learning\Angular2\cli called ProveIt. I'll navigate to D:\Dev\Learning\Angular2\cli in my command prompt and run ng new ProveIt. Creating the project using the CLI is the easiest way I've found.  You should be aware that the CLI uses Webpack so if you come across some bit of help (that's probably outdated) that talks about SystemJS, that probably won't work for you if you're following this guide.  ng new initializes git and installs a ton of npm packages for you so it takes a few minutes to complete.  Once it does finish, though, you actually have a working, testable application.  To prove it you can navigate into the directory you created (for me, that's D:\Dev\Learning\Angular2\cli\ProveIt) and run the command ng serve --open.  That will build your Angular 2 project, host it on port 4200, and launch your default browser to the root level of the application.  You should see a message that says (as of this writing) "app works!".  Congratulations!  You've "written" an Angular 2 app!

So now we have the default app running, which is a great start, but it isn't really an application.  At least, it doesn't do anything.  Let's use the CLI to add a new component to the application, called students.  Open a new command prompt and navigate to your new project (D:\Dev\Learning\Angular2\cli\ProveIt).  From there you want to go forward to src/app and run the command ng g component students.  This command is much faster, and creates four new files and modifies one file.  It's time to open our application.  I prefer VS Code, but you can use whatever you want.  Open the ProveIt folder and we'll explore some of the files that have been created so far.

.angular-cli.json

This is the configuration file used by the CLI to bootstrap the application when you run ng serve.  The CLI includes a built-in SASS parser so one of the first things I always do is change my styles.css to styles.scss and update this file to reference the .scss file instead of the .css file (line 22 as of this writing, but it's in the "styles" array).  If you want to include any 3rd party scripts (like Bootstrap) you'd add their relative path (assuming you added them via npm they'd be in node_modules/...) to the "scripts" array.  Finally, if you have nested directories with assets you want to deploy (like images or customized fonts) you'd add those to the "assets" array.  Just adding the top-level folder should be enough to include the entire directory in the output.

index.html

This file is the only file initially loaded by the application. Since Angular is focused on creating Single Page Applications (SPAs) this is that single page. From here on out everything that gets loaded just enhances the DOM or functionality of this one page. If you look in the <body> tag you'll see that we start off with an unknown (at least to HTML) tag called <app-root>. As we'll see in a few paragraphs this is actually an Angular component. Just keep this in mind as we move forward.

src/main.ts

This is essentially the entry point for the compilation of your application. I'm not going to lie and tell you I know exactly how this works, because I'm still a little murky on it, but I can tell you that it's where your browser gets told which module to start with. It should be defaulted to AppModule.

src/app/app.module.ts

This is the declaration of the AppModule.  You can see at the end of this file that AppModule is exported, which allows it to be used by main.ts as the bootstrap module.  You can also see that this file imports the necessary modules from various @angular folders that you're going to need to run this application in the browser.  Finally, there are two components imported and listed in the declarations section.  Part of using the Angular CLI to generate a new component (like we did earlier) is that the CLI will edit this module to import and declare your new component automatically so you don't have to worry about that part.

src/app/app.component.ts

This is where the actual AppComponent is declared and exported so it can be used in the AppModule as the bootstrap component (which means it's where the whole application starts).  You can see that the Component recipe is imported from @angular/core and then the class (AppComponent) is decorated with the @Component decorator, which specifies the selector for the component, the location of the template for the component, and the location of the stylesheet for the component.  This component has a single property, called title.

src/app/app.component.html

This is the markup that will be injected wherever Angular 2 finds our app component being used.  In other words, when we use <app-root></app-root>, Angular 2 will inject whatever is in this template file inside those tags.  Right now it's just a placeholder that displays the title inside of an <h1>, which is why we see "app works!" when we run the application.  The value of title is being set in app.component.ts and then displayed here.

If we examine the students.component.ts and students.component.html files that were created by the Angular CLI we'll see that they are very similar to the app.component.* files we just looked at.  Components are the basic force within Angular 2.  Components allow us to manipulate the DOM to do and show what we want.  One thing we haven't done yet is use our StudentsComponent in our application.  Let's go back to index.html and take another look.  Knowing what we know now about our AppComponent and its selector we can see that Angular is being told to inject the contents of src/app/app.component.html between the opening and closing <app-root> tags.  We want to do basically the same thing with our StudentsComponent so let's make that happen.  Open src/app/app.component.html and replace {{title}} with <app-students></app-students>.  If you left Angular CLI serving the application then just look at that tab in your browser again and you should see that the message has changed to "students works!".  What's happening is that Angular finds the <app-root> tag and injects the contents of the AppComponent in there.  While Angular is injecting that content it comes across the <app-students> component and realizes it needs to inject the contents of students.component.html into the AppComponent markup.  Since the content of our StudentsComponent is a simple message that says "students works!" (as you can see by opening src/app/students/students.component.html) that's what we see in our browser.

I'm going to end this post here because I think there's been a lot to digest so far.  This will only be the first in a series that I'll hopefully get up pretty quickly.  I'm still learning Angular 2 so don't take what I say as absolute truth.  Remember that I'm just putting up my thoughts to help me out in the future.

Sunday, March 19, 2017

Gitting Started with Git

I've recently switched from using TFS to using Git as my Version Control System of choice.  Some folks have been having issues making the transition so I put together a guide to get them through the process and I wanted to share it here for others.

The first thing I want to do is put a disclaimer out that I stole the name of this post from a session at Desert Code Camp last year.  Sorry, dude who presented it.  It was catchy.

I may edit this post in the future with some shortcuts and stuff, but for now here's a link to the slideshow I put together to present at work: https://docs.google.com/presentation/d/1KOc1M4KlXgzvdoRhjkcaZ8FeSOoN0z1RVnI8odSZo_0/edit?usp=sharing

Saturday, February 11, 2017

Testing Resolves in Jasmine

I've come across this issue before and I came up with a different answer (I think), but I can't remember that answer and I can't find it here.  So today I'm posting my new answer so at least I have this one for next time.

I'm using Angular UI Bootstrap's modal control to... open a modal.  I suppose that's kind of obvious.  Anyway, when you open a modal you can pass functions in that get resolved in the controller.  I'm not going to explain that in great detail here.

My problem was testing those resolves in my modal instance controller.  The resolves look something like this:
resolve: {
    student: function() {
        return {};
    },
    title: function() {
        return 'Add a Student';
    }
}

Since they're functions, UI Bootstrap is going to handle resolving them (get it?) to their returned values.  So when the controller loads, student will be an empty object and title will be that text.  When I test the modal instance controller I'll just be sure to inject those resolved values instead of functions.  It looks like this:
beforeEach(inject(function(_$rootScope_, _$controller_) {
    scope = _$rootScope_.$new();

    _$controller_('studentController', { $scope: scope, title: 'Add a Student', meal: {} });
}));

Now in my tests I can use those values the same way they'll be used in the actual code.  I answered a question on Stack Overflow about this topic a while back, but I can't recall what code I was looking at that prompted me to go looking for an answer that lead me to that question that I was able to answer.  Anyway, here's my answer on SO: http://stackoverflow.com/questions/37023953/unit-testing-ui-router-with-resolve/37075491#37075491