NHL Command Line App
Tags: hockey, ruby, cli
Published: 2021-03-01 14:12:54

I was able to finish the Flatiron School's Phase 1 Final Project, which calls for creating a command line interface app in Ruby that pulls data from a remote source uses that data in an object oriented program. I eventually opted to create a program that gives the user information about any NHL franchise's first year in the league. With a week to complete it start to finish, I hit a few challenges and some breakthroughs until I was ready to call it complete and have my parents display it on their refrigerator. I'll give the play-by-play, and color commentary, on how I was able to get to the final buzzer.

The first order of business was to brainstorm concepts for my app. I toyed with the idea of randomly generating and displaying a year to the user, and they have multiple choices to select which team won the Stanley Cup. As a fallback option, I came up with the idea to have the user type in their birth date and the app would display what the number 1 song in the charts (which specific chart depended on which chart API I was able to pull from). With 2 strong contenders in my back pocket I started researching APIs. RapidAPI.com seemed like a great resource, as it has a clean and simple search function to browse categories. I found a Billboard Chart API, which pushed me in the direction to create my Chart Topper birthday app (The hockey ones had a dizzying amount of statistical data to parse through, which I found discouraging). I started coding my model, when I realized I had not properly researched the API's endpoints (these are new concepts that though I understand in theory, it wasn't intuitive to me yet). The data being displayed was limited strictly to the current charts! Back to the drawing board it was- that was not enough depth of information to pass project requirements no matter what I did with it.

With a little bit of guidance, I reverted back to my hockey-themed app idea, but from an API with very simple endpoints (https://github.com/dword4/nhlapi). It was getting to be mid-week, and I wanted to simplify my model. The endpoint I elected to pass into my project showed an array of every NHL team, with a hash containing roughly 20 key/value pairs showing information from the city they play in, the conference and division they're a part of, home arena, first year of play, etc. It was the latter data point that I decided on to be the focus of my app. This made for a much more simplified idea than my previous ones, but I leaned into the rule of MVP- no I'm not talking about the Hart Trophy winner- but Minimum Viable Product. My goal was focused mostly on creating crisp, clear code, and properly separating concerns among the classes I would be writing.

My API class was simple, and only called upon first running the program. Following the specs from my source API, I set my response to a variable, and parsed through it with the JSON gem to get nicely formatted data. I passed the array of individual teams through a .each iteration, where each element of the array would create a new instance of my 'Team' class.

My Team class would be responsible for storing my list of NHL Teams, that are created upon initialization. As previously mentioned, each team it's own hash of data- in my Team model I meta-programmed getter and setter methods only for the data that I wished to work with in my program- the team's name, their first year of play, and their official website. Additionally I set class methods to alphabetize each team by name, and to find each team by name as those would prove essential once I started writing my CLI class.

For my CLI class, I had the challenge to take that team data and find a way to display it appropriately for the user. My original plan was to display my alphabetically ordered and numbered list of teams, and take input via the gets.chomp method- then save that input to a variable, and pass it in as an index number to the full array of teams. The corresponding (adjusted for index value of course, as my list starts at 1) team would get displayed with their name, first year in the league, and website through my 'display' method that I wrote and formatted. This was not as clean as I would have liked though- for it to work, I'd have to have all 31 teams showing in the terminal, which looked unwieldy, and I'd have to code in all sorts of conditions to make sure the user input was valid. This made for unnecessarily messy, ugly code.

Coming in like a trade for a star player at the deadline, I discovered (through my excellent classmates) a gem plug-in called TTY::Prompt (https://www.rubydoc.info/gems/tty-prompt). Learning this amazing tool was a gamechanger in my application: it let me format and display menu data as I wanted, and gave all sorts of customizable scrolling options. Once the gem is installed, set a variable equal to a new instance of TTY-Prompt (in my case, I used a constant in my environment file). On that variable or constant, all I had to do was call whichever method detailed in the gem documentation worked for what I was going for. I used PROMPT.select(then it took an argument for a customized user prompt, how many choices to display, etc.). I saved whatever user input they chose into a variable, and passed that variable on to my corresponding Team class method, to display just that team's data. I coded in a prompt to either display the list of teams again to make another choice, or to exit the program.

My command line interface application reflected the subject that I made it about- hockey. In hockey, often times the best results come from simplifying the game and committing to fundamentals. I believe my project does just that.