“Although no one can go back and make a brand new start, anyone can start from now and make a brand new ending.”
-Carl Bard
Wow, I cant believe we have arrived already to the end of 2019! This year has been a journey for sure. I think it's safe to say looking back that the journey was not exactly what I was expecting or hoping for, but I'm thankful for taking the road nonetheless. I have learned so much this year getting myself immersed in web development, as it has helped me develop my technical and problem solving skills.
My learning has given me the confidence to take the next steps in doing web development professionally, and I wanted to give an update on the steps I will be taking to ensure this happens in 2020.
I think one of the missteps I had this year was not taking enough to jump in there and just code. While I have been doing a ton of learning through Pluralsight this second half of the year, sometimes there is just no replacing hand-on experience. So, I have taken some time the last couple of months to get a few projects off the ground, and into a live production environment that people could check out and see for themselves. Here are two personal projects I have finished:
On top of these project, I am also looking at building an my own API using Python and Flask. It will probably revolve around something TV related, but more to come on that front.
As you may have noticed, my blog has undergone a complete redesign. While the first attempt was a valiant effort at putting together a complete website, I just felt like my UI design was not very pleasing to the eye and wasn't very clean. So, knowing my design skills are not necessarily my strong suit, I looked to other solutions to build and design my site. In that process, I discovered Gatsby.js, which is a static site generator based on React. The number of templates available were awesome, and much better than anything I could have designed on my own. So, I picked a template I loved, and set up a website that I am proud to put out as my own.
Between my experience creating reporting and dashboards for a Fortune 100 company, and my new found abilities in web development, I am getting ready to launch a new business venture! This is exhilarating and terrifying to me at the same time, but I think is a necessary step for me to meet my long term goals in achieving financial independence.
My focus is going to be primarily on developing web applications that can help small businesses gather information and gain actionable insights from that information, as well as automate tasks that will save them time that can be used to grow their business.
If you want more information and details, or have any referrals you want to send my way, you can submit that info for now through the contact form on this site.
While I would love for my new business to ultimately be my meal ticket out of corporate america, I recognize that effort will take years to accomplish. In the meantime, I know the best way for me to ultimately develop my tech skill sets and learn is to do so in my full-time day job. So, I'm going to restart my efforts to find a position that will help me to accomplish that goal. So, I plan on spending a lot of time at different tech meetups these next few months, and meeting people that will help me to achieve that goal.
I wish everybody a very happy holiday season as we all wrap up 2019, and a happy new year in 2020. I look forward to sharing more updates with you as I continue to press on with my web developer journey!
"Television provides the opportunity for an ongoing story - the opportunity to meld the cast and the characters and a world, and to spend more time there." - David Lynch
There is no getting around it, I love TV shows! Just like a good book series or movie franchise, TV shows allow you to spend some time in a world with your favorite characters and engage with a great story.
While I don't have the time to binge watch an entire TV series in a matter of weeks like I used to circa 2011, I still try to take at least 1 hour at the end of the night to take in a show (and then usually have to start that show over multiple times since I usually fall asleep within 15 minutes of starting it).
Since we are in the mist of what has been officially dubbed Peak TV, I've found that its sometimes difficult with the sheer amount of TV to choose from to get through the clutter and figure out what to watch (I cant tell you how many hours I spent just browsing through Netflix and Amazon queues just to figure out what to watch). I frequently am seeking out TV podcasts with critic reviews to figure out if a TV show is worth my time. So, to pay it forward, I thought I would share a handful of TV shows that I have watched and really enjoyed this year.
Writing this post has also inspired an application idea that I'm hoping to start soon, so more to come on that front!
I've focused on shows where I have finished their most current season, and in a few of the cases, where the shows have ended their runs, so you could jump in and watch the whole series.
I also am going to throw in a throwback series that I spent some time with this year.
Coming from the mouths of former White House aides, Veep is the most real show depicting what life is really like inside a politicians staff and the day-to-day in Washington (at least I would hope so, things might be pretty dark if it were more like House of Cards).
If it's not clear from the name, this show follows fictional Vice-President Selina Meyer and her staff.
Be forewarned, this show is not for the faint of heart. The characters are cruel, ruthless, and the show approaches levels of profanity that few shows have reached. That being said, there are also not very many shows that have caused me to laugh out loud as much as this show has. What this show really demonstrates to me is that ultimately, there is a lot of incompetence in the world (I'm sure in our own careers, we know plenty of people that we would classify as incompetent), and the government is not immune from it.
As bad as I hear Solo: A Star Wars Story was as a movie, I would venture to say that more people know Phoebe Waller-Bridge as the voice of L3-37 than as the creator and star of Fleabag. If that is the case though, you are surely missing out
Fleabag is simply the story of a young woman in London trying to cope with her life and come to terms with a recent tragedy. It's a comedy overall, so their are more laughs than anything. At the same time, it takes on very serious topics, which include grief, and how to cope in a world that sometimes doesn't make sense. This show also frequently breaking the 4th wall (where Fleabag frequently talks directly to the audience) which adds context and laughs throughout. This show also recently won a slew of Emmy's, including Outstanding Comedy Series and Outstanding Lead Actress for Phoebe Waller-Bridge. With some of the projects she is working on (Killing Eve, which is another great show to check out, and the new James Bond film coming out in 2020), you'll know who she is sooner or later, so you might as well jump on the bandwagon now!
Oh, and to add, the series is very short (which I am appreciating more and more as my time becomes less and less). You can wrap up the whole series in 4 hours!
There are a few types of shows that always draw me in (Shows focused on the criminal underworld, the lifestyles of the rich and famous, and as of late, singing competitions where everybody is dressed up in elaborate costumes and you have to guess who they are). One of those types of shows involve rich people running high stakes corporations. So, naturally, Succession was right up my alley from the start.
Succession follows Logan Roy, the head of a global media conglomerate, and his family as they navigate their relationships with each other, positioning themselves for more power in the organization, and just living the life of the obscenely rich.
The show is extremely witty, and finds a way to get you invested in the horse race the characters are engaged in. For a set up of characters that really should not be likable, they all find ways to relate to the audience. For example, Kendall Roy takes me back to my boyhood fantasy of being a successful rapper:
With my second British show to enter the list, Catastrophe is another delightful show show that also is on the shorter side time wise, and can be wrapped up really quickly.
Catastrophe is the story of Rob and Sharon, two singles who end up getting together after Sharon unexpectedly becomes pregnant. The show does a great job of showing the up's and downs that can occur with a couple, and how their relationship evolves over time. It's struck me as being an honest look into how relationships and marriages really are, but also did a great job of capturing the lighter moments in an gleeful way.
I cant believe it took me 16 years to catch on to The O.C. , but I suppose it is better to be late than never!
The O.C. is a teenage drama set in Orange County, CA. Bad Boy Ryan Atwood finds himself on the wrong side of the law, but lucks out when public defender Sandy Cohen offers to take Ryan in. Ryan goes from being in a dysfunctional situation in Chino, to the rich/posh world of Orange County.
This show was wild when it came to the drama. Here is just a taste of some of the crazy storylines this cast endured
I could go on, but I wouldn't want to spoil it for those who haven't had the chance. While this show would likely not make my top 10 shows of all time, it was a really low stress, enjoyable watch.
That's my list. Hit me up in the comments and share your favorites!
"Everyone should know how to program a computer, because it teaches you how to think!"
-Steve Jobs
Whew, it has been a busy summer! But, I am ready to resume blog posts and can hopefully be a little bit more regular.
From a code perspective, I have been learning a few different concepts and languages. I have started learning Angular (which has a lot to like!) and started a project built in Angular which is going to house the balances of my kids bank accounts (For background, anytime my kids get money for their birthday, Christmas, or doing extra chores, I tell them to just give me the money, and I will put it in their bank account, and that I pay a generous interest rate if they save it :)). I hope to have more on that in another post.
For today though, I want to share the next phase of my cocktail database project. In my last post, I detailed how I did an API call from a React front end, through the rails back end, and ultimately to the API endpoint. Once I figured out some Ruby Gems I could use to make the API call easier, it was pretty simple to call the API for a random cocktail recipe.
The next task, which was a little more tricky, was to actually make a call to the API with a user input search to find specific cocktails. This was more difficult for a few reasons:
1. I had to set up the React end to accept an input, handle the change in the input, and make the api call via axios
2. I had to make sure the search input was being passed correctly to the axios call so the rails backend knew what to do with the information
3. I wanted to make this a live search, the the cocktails that were presented showed up in real time as I typed
This step should have been easy enough to do since I had already set up the backend previously through the API call to get a random cocktail. That setup ended up being really easy though because with that API call, I was not sending over any parameters, it was simply a call to return a random JSON response. To make the call with parameters, I had to do some additional research and some additional troubleshooting to figure it out. I was able to add an additional method using the RestClient Ruby gem, with some additional setup to accept the search parameters:
require 'rest-client'
class Cocktail
...
def search_cocktail(search)
RestClient.get('https://www.thecocktaildb.com/api/json/v1/1/search.php', {params: {s: search}})
end
end
Then, I had to set up the controller to accept the parameter, and send back the result:
class Api::CocktailsController < ApplicationController
...
def show
search = Cocktail.new
@cocktail = search.search_cocktail(params[:id])
render json: @cocktail
end
end
I will admit, I had a little bit of a hard time getting the RestClient to accept the parameter correct, and then getting the controller set up just right to accept the parameter and send back the correct results. It was through this process that I got my first real experience utilizing Postman for troubleshooting API calls, which was awesome!
For those who aren't aware, Postman is an application that is great for API management, and where you can easily make API calls, and see the results. What I didn't realize before building this feature was that the program also worked with localhost.So, with that discovery, it made debugging and troubleshooting much easier!
This step ended up being very similar to what I did with the Random Cocktail component. Passing the data through axios to the backend wasn't too bad. I just had to make the call to the right rails route through the search function:
search = async val => {
this.setState({ loading: true });
const res = await axios(
`/api/cocktails/${val}`
)
const cocktails = await res.data.drinks;
this.setState({ cocktails, loading: false })
if (this.state.value === '') {
this.setState({ cocktails: ''})
}
};
Where this ended up getting a little tricker was with the search functionality. With Live Search, it has to be set up where it triggers an API call as the characters are getting typed. This was something I was not super familiar with before, but utilizing Semantic-UI's search module set up, it gave me some great insights into how to set up the search box to do some cool setup (such as a loading indicator), and also how to handle changes in the search box and trigger the search function to run.
Here was the final code for the setup of the Search Component:
import React, { Component } from 'react';
import axios from 'axios';
import { Search, Button, Modal, Segment, Image } from 'semantic-ui-react';
import CocktailSearchDetail from './CocktailSearchDetail';
const style = {
background: {
position: 'absolute',
textAlign: 'center',
backgroundColor: '#E4FAFF',
height: '100%',
width: '100%',
padding: '50px',
}
}
class CocktailSearch extends Component {
state = {
cocktails: '',
loading: false,
value: ''
};
...
onChangeHandler = async e => {
this.search(e.target.value);
this.setState({ value: e.target.value });
};
renderCocktails = () => {
let noCocktails = <h3>Could not find a cocktail, try again</h3>;
if (this.state.cocktails) {
const drinks =
this.state.cocktails.map( (drink) => {
return (
<div style={{display: 'inline-block', padding: '10px 10px 10px 10px'}}>
<Image src={drink.strDrinkThumb} size='small' />
<h3>{drink.strDrink}</h3>
<Modal trigger={<Button>See Details</Button>}>
<CocktailSearchDetail key={drink.idDrink} {...drink}/>
</Modal>
</div>
)
}) ;
return drinks
} if (this.state.cocktails === null) {
return noCocktails;
} else {
return (<h3>Fun Awaits! Just Enter a Search</h3>)
}
}
render() {
return (
<>
<div style={style.background}>
<h1>Search for a Cocktail</h1>
<br></br>
<Search
value={this.state.value}
onSearchChange={e => this.onChangeHandler(e)}
loading={this.state.loading}
showNoResults={false}
/>
<br></br>
<h3>Search Results:</h3>
<Segment raised style={{marginLeft: 'auto', marginRight: 'auto', width: '75%'}}>
{this.renderCocktails()}
</Segment>
</div>
</>
);
}
}
export default CocktailSearch;
And to practice my handy dandy skill of prop drilling while creating some cleaner code, I set up a Modal component to pop up when selecting a specific drink:
import React from 'react';
import { Modal, Image, Table } from 'semantic-ui-react';
function CocktailSearchDetail(props) {
return (
<>
<Modal.Header>{props.strDrink}</Modal.Header>
<Modal.Content image scrolling>
<Image src={props.strDrinkThumb} wrapped size='medium' />
<Modal.Description>
<Table color='blue'>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Amount</Table.HeaderCell>
<Table.HeaderCell>Ingredient</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row style={props.strIngredient1 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure1}</Table.Cell>
<Table.Cell>{props.strIngredient1}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient2 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure2}</Table.Cell>
<Table.Cell>{props.strIngredient2}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient3 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure3}</Table.Cell>
<Table.Cell>{props.strIngredient3}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient4 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure4}</Table.Cell>
<Table.Cell>{props.strIngredient4}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient5 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure5}</Table.Cell>
<Table.Cell>{props.strIngredient5}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient6 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure6}</Table.Cell>
<Table.Cell>{props.strIngredient6}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient7 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure7}</Table.Cell>
<Table.Cell>{props.strIngredient7}</Table.Cell>
</Table.Row>
<Table.Row style={props.strIngredient8 === '' ? {display: 'none'}:{}}>
<Table.Cell>{props.strMeasure8}</Table.Cell>
<Table.Cell>{props.strIngredient8}</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
<p>Instructions:</p>
<p>{props.strInstructions}</p>
<br></br>
</Modal.Description>
</Modal.Content>
</>
)
}
export default CocktailSearchDetail
This got me to quite a nice spot on the search screen. I think I actually impressed myself for once on how I did this :)
I am now one step closer to having a nice, productive application. I have some more work to do. I want to build quite a few features into this application:
1. The ability for user authentication, so a user could save their favorite recipes (With OAuth2, so people can sign in with one of their other services)
2. Enable search to work with other categories, such as by ingredients, etc.
Those will have to come another day. For now, check out the code in my Github Repo. I hope to add these additional features soon so I can launch a live product into production for all of you to try.
"Let's call it an accidental feature."
- Larry Wall
As I have continued my learning experience in this web development adventure, one area that I have tried to focus on is how to integrate API's into the web applications that I build. With the abundance of information available in different API's out there, it's an important skill to know if I want to have access to a lot of information.
Trying to get an API integrated into Rails, and have that information passed to a React front-end was an interesting feat, so I thought I would share my process.
For the purposes of this demo, I found an awesome API that contains a large database of Cocktail recipes called The Cocktail DB.
Since I wanted my API to go through a back-end (mainly because I wanted to build in OAuth into the app, and have a database in place for users to store their favorite recipes), I had to figure out how to get the API call to route through Rails.
This ended up requiring two steps. One was building the object to make the API call, and the other was building a method in the Rails controller for the front end to call.
The API call step ended up being pretty easy thanks to a Ruby Gem called REST Client. All I had to do was build a ruby class that could be called upon by the controller:
require 'rest-client'
class Cocktail
def get_random_cocktail
RestClient.get('http://www.thecocktaildb.com/api/json/v1/1/random.php', {accept: :json})
end
end
With the API call set up and ready to go, I then set up a cocktail controller that would initiate the API call when the get_random_cocktail method was run:
class Api::CocktailsController < ApplicationController
def index
random = Cocktail.new
@cocktail = random.get_random_cocktail()
render json: @cocktail
end
end
With the back-end set up, I am now in a position to set up the front-end to read the data of the API calls.
However, there is one important step to take into account to make sure the back-end and front-end are allowed to speak to each other, and that is to enable Cross-Origin Resource Sharing (CORS)
In layman's terms, our Rails back-end runs its server on Localhost:3001, while the React front-end runs its server on Localhost:3000. If we want the two servers to be able to transmit data to each other, we have to explicitly allow this.
This is also a fairly easy step. When a new rails application is created, it already has all the necessary code built in, its just a matter of un-commenting the code,
In our Gemfile, we would activate the "rack-cors" gem:
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
gem 'rack-cors'
And then, we would need to un-comment the middle-ware initialization in the cors.rb file under config/initializers:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:3000'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
Now that the back-end is all set up and ready to go, lets set up our front-end to make an API call to our back-end. I have set this up to occur via the Axios NPM package, and utilizing React Hooks:
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {Card, Image, Icon} from 'semantic-ui-react';
import Navbar from './Components/Shared/Navbar';
function RandomCocktail() {
const [drinkInfo, setDrinkInfo] = useState( '' )
useEffect(() => {
async function fetchData() {
const result = await axios.get('/api/cocktails');
setDrinkInfo(result.data.drinks[0])}
fetchData();
}, [])
}
Add in some styles and basic formatting:
const style = {
center: {
display: 'block',
marginRight: 'auto',
marginLeft: 'auto',
},
background: {
backgroundImage: "url('')",
height: '100%',
width: '100%',
},
list: {
listStyleType: 'none',
display: 'inline-block',
},
container: {
paddingRight: '33%',
paddingLeft: '33%',
},
}
const ingredientList = () => {
const ingredients = Object.entries(drinkInfo)
const result = []
ingredients.map((x, i) => {
if ((ingredients[i][0].includes('Ingredient') === true)
&& (ingredients[i][1] !== "") && (ingredients[i][1] !== null)) {
result.push({ ingredient: ingredients[i][1] })
}
})
return result
}
const measureList = () => {
const measures = Object.entries(drinkInfo)
const result = []
measures.map((x, i) => {
if ((measures[i][0].includes('Measure') === true)
&& (measures[i][1] !== "") && (measures[i][1] !== null)) {
result.push({ measure: measures[i][1] })
}
})
return result
}
return (
<>
<div style={style.background}>
<h1 style={{textAlign: 'center', color: 'white'}}>Cocktail of the Day</h1>
<br></br>
<div style={style.container}>
<Card style={style.center} fluid>
<Image src={drinkInfo.strDrinkThumb} centered size={"huge"} />
<Card.Content>
<Card.Header>{drinkInfo.strDrink}</Card.Header>
<Card.Meta>
<ul style={style.list}>
{measureList().map((x) => {
return <li key={x+1}>{x.measure}</li>
})}
</ul>
<ul style={style.list}>
{ingredientList().map((x) => {
return <li key={x+1}>{x.ingredient}</li>
})}
</ul>
</Card.Meta>
</Card.Content>
<Card.Content extra>
<Card.Header>Instructions</Card.Header>
<Card.Description>{drinkInfo.strInstructions}</Card.Description>
</Card.Content>
</Card>
</div>
<br></br>
<br></br>
</div>
</>
);
}
export default RandomCocktail;
And Boom! We now have a basic website populating the information from the API:
There is a lot more to this site that needs to be worked on before I post the live demo. In the meantime, you can check out my GitHub repo to see the full project
"He dares to be a fool, and that is the first step in the direction of wisdom."
-James Huneker
Wow, I started a blog! And i'm doing it on my own personal website. It's just crazy enough that it might work.
If you have gotten to this post, I'm guessing you have seen the About Me page of the site and gotten a little bit of background about me. But for my first blog post on the site, here's some extra information that you might not have seen coming:
Here is a quick overview of left brain/right brain theory if you are not familiar.
For those that know me and have seen me in action, I definitely gravitate towards being a left brain. I value logic probably to a fault, I analyze items heavily to make the best decisions, and I seek to sort fact from fiction. My left brain is what has helped me be successful in my career so far, and is what has driven me towards getting into web development. I love my left brain, and look forward to having it for the long haul.
At the same time, I have consistently throughout the years had an itch for the creative side, and really want to figure out the best way that I can express myself creatively. Here are a list of things I have at a minimum researched for more than a few hours:
Some of these have merely been research and never attempted (Stand Up Comedy fascinates me, but scares me to death!). Some I have put to toe in the water (I scribbled some ideas for a book, made some small videos I put on Facebook, and bought a cheap drone so I could learn to fly). Others I have put in a ton of effort only to not end up releasing anything publicly (I had a whole blog set up dedicated to weight loss, but ended up abandoning the project. Partially due to laziness, but also due to fear).
I did make an attempt at a sports blog 10 years ago that was public and shared on Facebook. I just re-read some of those posts and cringed.
I'm hoping this blog can be a first step in helping me develop the creative side of my brain, which can only help me as I start my web developer journey.
Nothing bring me more joy in life than to travel to new destinations with my family. My wife and I have made a commitment to travel to a new continent for each 10 year anniversary. Our first 10 year milestone was last year, when we went to Europe and explored Paris, London, and Edinburgh:
My all time dream would be to work remotely while traveling the world. While thats not super feasible at the moment due to school and athletic activities for the kids, its something I want to strive for someday (Maybe in my 50's after the kids are out of the house, but still young enough to somewhat move around).
Seeing as the overall website is intended to be a portfolio website to show off my web development capabilities, I'm certain that there will be a lot of tech related posts chronicling my developer journey, and a bunch of posts detailing stuff I have learned along the way.
I'm certain I will have some opinions about the upcoming offseason for the Utah Jazz.
I'm sure I will have some hot takes the next time a Marvel movie comes or I discover a TV show I love.
I'm obsessed with investing, and have lofty goals to retire in my 50's with lots of passive income coming my way, and would be eager to share my successes (or lack thereof).
Either way, my hope is that this blog will continue on, and be something that I can look back on and be proud of. That will only happen if I am 100% authentic, so that is my intention from here on out.
I look forward to this journey, and thank you for reading and indulging me. I hope that you find some value from what I write.
I'll still be sure to write plenty of click bait posts just in case :)
Cheers!