Bootstrap 4

The continuation of the AngularJS, Rails, Webpack tutorial will be back next week. I have been working on a site this week and it was my first foray into Bootstrap 4. I didn’t know what I was getting into at first. I thought, like most updates, that the power of the framework just got stronger and things got easier. Little did I know that it was a complete rewrite!

Flexbox

The Bootstrap 4 rewrite takes advantage of the Flexbox model, something I haven’t delved into much so far. What does it mean for using our beloved containers, rows, and columns? Not much. Things might look different behind the scenes, but up front things mostly look the same. One major thing to think about when migrating a site or starting a new site with Bootstrap 4 is that it is not compatible with Internet Explorer versions 8 and 9. Personally, I wish IE would die a quick death.

Cool Changes

Much has been dropped from Bootstrap 4 as the web has moved on from certain things. To see a full list, check it out here. One thing I thought that was cool is the less bulky navbar. This is how we’re used to seeing the HTML for a navbar…

<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <a class="navbar-brand" href="#">Navbar</a>
  <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Features</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Pricing</a>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
    </ul>
  </div>
</nav>

It’s so bulky, right? Well check this out…


<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <a class="navbar-brand" href="#">Navbar</a>
  <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
    <div class="navbar-nav">
      <a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
      <a class="nav-item nav-link" href="#">Features</a>
      <a class="nav-item nav-link" href="#">Pricing</a>
      <a class="nav-item nav-link disabled" href="#">Disabled</a>
    </div>
  </div>
</nav>

Notice anything missing? Well the top half is the same, but take a look at the links. No more ul’s and li’s. This is because they use classes for the navs now.

You can also size very easily with inline attributes. 25%, 50%, 75% and 100% widths and heights can be achieved by using ‘w’ for the former and ‘h’ for the latter. Then just add a dash and the desired number, such as h-100. Here’s an example.

<div class="w-25 p-3" style="background-color: #eee;">Width 25%</div>
<div class="w-50 p-3" style="background-color: #eee;">Width 50%</div>
<div class="w-75 p-3" style="background-color: #eee;">Width 75%</div>
<div class="w-100 p-3" style="background-color: #eee;">Width 100%</div>

Screen Shot 2017-10-06 at 3.41.21 PM

And for heights…

<div style="height: 100px; background-color: rgba(255,0,0,0.1);">
  <div class="h-25 d-inline-block" style="width: 120px; background-color: rgba(0,0,255,.1)">Height 25%</div>
  <div class="h-50 d-inline-block" style="width: 120px; background-color: rgba(0,0,255,.1)">Height 50%</div>
  <div class="h-75 d-inline-block" style="width: 120px; background-color: rgba(0,0,255,.1)">Height 75%</div>
  <div class="h-100 d-inline-block" style="width: 120px; background-color: rgba(0,0,255,.1)">Height 100%</div>
</div>

Screen Shot 2017-10-06 at 3.41.43 PM

I’ve been working a lot this week so I’m going to leave it off here. I’ll be back next week for the continuation of the tutorial. Peace!

Advertisements

Using ES6 Syntax in React

I don’t know about you, but I love the changes made in ES6. I’m currently learning React and ES6 definitely makes life much easier. I’ll talk specifically about Arrow Functions and why using them will help make you coding your components much more fun.

The Olde Way

Let’s take a look at a simple pre-ES6 component.

import React from 'react';

class WhatsUp extends React.Component {
  constructor() {
    super();
    
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    // 'this' is only reachable because of the binding in the constructor above
    // otherwise it would be scoped to handleClick's environment and the log 
    // would be undefined 
    console.log(this.props.message)
  }

  render() {
    return (
      <button onClick={this.handleClick}>Click Me</button>
    )
  }
}

export default WhatsUp

The main takeaway here is the binding of the ‘this’ keyword. Without the binding in the constructor, when we used ‘this’ inside of a function, it would be referring to the functions ‘this’ – not the class.

How the Cool Kids Are Doing It

The cool thing about Arrow Functions is that they don’t bind their own ‘this’. What do the Gods say?

From our friends at Mozilla:

An arrow function expression has a shorter syntax than a function expression and does not bind its own this, arguments, super, or new.target.

Until arrow functions, every new function defined its own this value (a new object in the case of a constructor, undefined in strict mode function calls, the base object if the function is called as an “object method”, etc.). This proved to be annoying with an object-oriented style of programming.

That means we don’t have to worry about binding the function in the constructor. Take a looksie…

import React from 'react';

class WhatsUp extends React.Component {

  handleClick = (event) => {
    // 'this' is not bound to the handleClick function so we can use it freely
    console.log(this.props.message)
  }

  render() {
    return (
      <button onClick={this.handleClick}>Click Me</button>
    )
  }
}

export default WhatsUp

Look at that – we don’t have to use a constructor! Pretty cool. You might think, ‘Eh, no biggie’. But what if we had many more functions that we had to bind ‘this’ to? That’s much more code we have to write and makes our files more bloated. I know if we had to set an initial state, we’d still have to write a constructor. However, we wouldn’t have to bind so many functions.

If you haven’t started using ES6, I strongly recommend it. It will save time and energy in the long run. The Spread Operator is probably what I use second most, after Arrow Functions. Try them out and be amazed! Until next time. Cheers:)

The Sneaky Way to Find a Developer’s Email Address

Searching for a job can be a full time job. I’ve heard this more than once since I’ve started my job search. One of the best ways to get an in at a company is to befriend a developer that already works there. You can research companies online, find your target company, and search LinkedIn for developers that work there. Then what? Well, you have to find their email address and try to connect.

The Standard Way

How I’ve done this up to date, is with a combination of two Chrome extensions: Hunter and Rapportive. Hunter allows you to search any domain and the search results will include many email addresses of the folks that work there. If your target isn’t on the list, no worries – we can see the email format that is used by the company from the search results. Now we can use Rapportive in Gmail to ensure we have the right email address.

Let’s say our target company Apple, the results from Hunter may look something like this:

info@apple.com
steve.jobs@apple.com
tim.cook@apple.com
etc…

If our target is Steve Wozniack, our results from Hunter did not give us what we were looking for. But wait! We can see the format Apple uses and make an educated guess. When composing an email in Gmail, we’ll try steve.wozniak@apple.com as the recipient, and most of the time Rapportive will let us know if it’s a valid email address. We should see something like this on the right hand side of Gmail.

Screen Shot 2017-08-20 at 11.00.12 AM

Not Steve Wozniak…A new app from the creators of Silicon Valley – a follow up to their wildy successful ‘Not Hot Dog’ app

Success! We know the email address is valid! Now we can craft a nice email, ship it off, and wait eagerly for a response. The problem is, I haven’t had much luck with this approach. I’ve sent so many emails out to developers with not much of a response. Enter the sneaky way…

The Sneaky Way

After discussing my job hunt with a seasoned developer the other night at a meetup, he showed me a sneaky way to find another dev’s email address. The only caveat being, they must contribute to open source. My lack of success might be attributed to the fact that I have been emailing company email accounts. The aforementioned seasoned dev told me – better luck will come if you can find their personal email address.

This method all revolves around Github. You can either look up their company on github or google github + the dev’s name. The latter way will ensure you are going to get your target’s email address. Once you’ve found the dev’s account, find a repository they worked on. Make sure it’s not a repo they forked or you’ll wind up with many other email addresses (and not necessarily the email you wanted). Now you’re going to clone the repo, copy it, and head over to your terminal and type ‘git clone ‘. ‘cd’ into the project and type ‘git log’. This should bring up all the email addresses that have committed to the repo.

In my case, however, this just showed me the dev’s names and the commits they made to the repo. Supposedly, there was something wrong with the formatting. Luckily, my new friend gave me a line of code that did the trick.

git log --all --format='%cN %Cgreen<%cE>%Creset' | sort -u

After running this in the terminal, all of the email addresses from the commits to the repo were displayed! Usually, this technique will give us their personal email addresses and we can send unsolicited emails all we want! Evil laugh…

Now to get people to respond. It was said to go as high up as you can in your target company. If there is a CTO – go for them. If not, try a Director of Engineering or a maybe Senior Dev. Keep your email short and sweet. It should only take the recipient 20 seconds or less to read. Include a very brief introduction, a small compliment (I really liked your blog post on such and such), and an ‘ask’ (can I buy you a coffee this week?). If they agree, keep the coffee meeting under 30 minutes and don’t keep them too long – people are busy! Don’t even mention a job. Treat the meeting like you’re making a new friend. If all goes well, they will bring up the topic of a job opening!

Have you had success with this or another technique? Leave a comment below – I’d love to hear about it. If you’re out there in the scary world of job hunting, hopefully this technique will help you! Until next time…Cheers:)

Using a Set For Faster Searching

Recently, I was working on a code challenge at CodeFights which specified that the solution had to run in O(n) time. The brute force solution was a nested for loop, but this would run in O(n^2) time. Here’s the code challenge:

Note: Write a solution with O(n) time complexity and O(1) additional space complexity, since this is what you would be asked to do during a real interview.

Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, return -1.

Example

For a = [2, 3, 3, 1, 5, 2], the output should be
firstDuplicate(a) = 3.

There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than than second occurrence of 2 does, so the answer is 3.

For a = [2, 4, 3, 5, 1], the output should be
firstDuplicate(a) = -1.

Input/Output

[time limit] 4000ms (js)
[input] array.integer a

Guaranteed constraints:
1 ≤ a.length ≤ 105,
1 ≤ a[i] ≤ a.length.

[output] integer

The element in a that occurs in the array more than once and has the minimal index for its second occurrence. If there are no such elements, return -1.

My first attempt to solve it worked but unfortunately was not quite fast enough and did not pass the last two tests. I created a new array to hold numbers that were already checked. In a for loop, in each iteration, the new array would be checked to see if the current number was included. If it was, then function would return the number. Take a look…

function firstDuplicate(a) {
    let visitedNumbers = [],
        i;
    
    for (i = 0; i < a.length; i++) {
        if (visitedNumbers.includes(a[i])) {
            return a[i];
        }
        visitedNumbers.push(a[i]);
    }
    
    return -1;
}

If the visitedNumbers array includes the current indexed number in the given array, then that number will be returned. If not, then the number is added to the visitedNumbers array and the next number in the given array is checked. If all the numbers are checked and none of them are duplicated, the function will return -1. Like I said earlier, this works, however it was not passing the last two tests, which I assume had very large inputs. After digging around a bit, I stumbled across something that I had not used before.

According to our friends at Mozilla, a Set is an object that “lets you store unique values of any type, whether primitive values or object references”. Ok, so how does that help us? Well according to this site, the Set method ‘has’ is 16% faster than the Array method ‘includes’. For small inputs, this won’t matter. But imagine a huge input; 16 percent would be very noticeable. Let’s see a Set in action.

function firstDuplicate(a) {
    let visitedNumbers = new Set(),
        i;
    
    for (i = 0; i < a.length; i++) {
        if (visitedNumbers.has(a[i])) {
            return a[i];
        }
        visitedNumbers.add(a[i])
    }
    return -1;
}

Now all test pass! Yay! Apparently this question is asked at Google. That makes me feel good about myself. The moral of the story: Sets are cool and fast. I’ll be using them more in the future. Until next time. Cheers:)

Vacation Time

I’ve been on vacation the last two weeks, which included a whole lot of moving around and not much time to think about programming. I don’t think I checked my email for 5 days straight. Honestly, it felt pretty good. Technology is wonderful, but there is a beautiful world beyond the bits and bytes that consume much of our attention.

It’s nice to get a breather every now and then. Coming back refreshed and still realizing you haven’t forgotten much is very nice. I’m still in Montreal until Monday, but wanted to write a little something to keep my blog up. If you haven’t been to Montreal, go now – in the summer! It’s a completely different city during the winter months, which can be quite brutal. I’ll be bringing back the technical part of the blog next week. Until then – happy summer:)

How to Clone a Website Using Chrome’s Dev Tools Part III

Alrighty then! We’re going down the home stretch. Let’s take a look at our remaining errors.

Screen Shot 2017-07-07 at 4.01.48 PM

Much better!

And this is what our clone looks like…

Screen Shot 2017-07-07 at 4.04.47 PM

This is what Carbon Five’s site actually looks like…

Screen Shot 2017-07-10 at 10.37.59 AM

Right off the bat, we can see that our fonts are not the same and we need the Carbon Five logo. Looking at the errors above tells us the same story. Let’s dig in and tackle each one of these errors. The first error is for a JS file called ‘v2.js’. After searching our index.html file, we’ll find the JS file being referenced in the footer as:

<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2.js"></script>

All we have to do is prepend the src link with ‘http:’. After refreshing our index.html file in Chrome, the error is gone. Easy peasy:) Next on our error list is for ‘file:///fonts/c5-logo.woff’. If we search our index.html file, we’ll find two lines of code referencing the styles for the font/logo. So that means we’ll search the app.css file. We’ll find this block of styles:

/* c5 icon font styles */
@font-face {
  font-family: 'c5-logo';
  src:url('/fonts/c5-logo.eot');
  src:url('/fonts/c5-logo.eot?#iefix') format('embedded-opentype'),
    url('/fonts/c5-logo.woff') format('woff'),
    url('/fonts/c5-logo.ttf') format('truetype'),
    url('/fonts/c5-logo.svg#c5-logo') format('svg');
  font-weight: normal;
  font-style: normal;
}

Let’s go check the sources in our console at carbonfive. When we click the images folder, there are two files – c5-logo.woff & pentel.woff. The ‘woff’ extension stands for Web Open Font Format. This file type for fonts is compressed so websites using these file formats should load faster. We can append ‘/fonts/c5-logo.woff’ to ‘carbonfive.com’ in Chrome and the file will download to our computer. All we have to do is make a ‘fonts’ folder in Atom and drag our recently downloaded file over and drop in. When we refresh the browser we’re still getting the error. So we probably have to change the way it’s being referenced.

Let’s prepend all of the urls from the c5 icon font styles above with ‘..’. This will bring us up two the root directory and then we’ll be able to access our fonts folder. Let’s refresh Chrome and see if we’re down a couple more errors. We are! We only have three errors to go:)

Screen Shot 2017-07-10 at 11.12.44 AM

Two of the errors look very similar to the ones we just took care of. Let’s try the same steps. First, append carbonfive.com with ‘/fonts/pentel.woff’ and open in Chrome. That should download the file. Next drag it over to Atom and place in the fonts folder. Now let’s do a search in our app.css file for ‘pentel’. We should find this block of code:


@font-face {
  font-family: 'pentel';
  src:url('/fonts/pentel.eot');
  src:url('/fonts/pentel.eot?#iefix') format('embedded-opentype'),
    url('/fonts/pentel.woff') format('woff'),
    url('/fonts/pentel.ttf') format('truetype'),
    url('/fonts/pentel.svg#pentel') format('svg');
  font-weight: normal;
  font-style: normal;
}

Looks very familiar! I think you’ll know what to do next. If you said ‘prepend the urls with two periods’, you are correct! After refreshing the browser we’re left with one error! Sweet!

**Just a note – the ‘pentel’ font is an Adobe font, which you’ll need a typekit password for. This is not a free font. It will work locally, but if you publish to github pages or something similar it will break.**

The last error has something to do with a Google API and from the look of the link, it’s specific to Carbon Five. This means only their devs have access to the API. In that case we’re done! Feel free to change images, fonts and styles. If you see a cool feature, try to figure out how they’re doing it – you have the code in your hands! I hope this was enjoyable for you. If you’re ever on a cool website and you want to see what’s going on under the hood, command + option + i. What did the world look like before Dev Tools? I don’t want to know!

How to Clone a Website Using Chrome’s Dev Tools Part II

We left off with turning some errors green. You can find the site we’re working on here. Once we got the bootstrap reference link to work, all of a sudden the site started to look like something real. It still needs some work though. This is where we’re at…

Screen Shot 2017-07-02 at 5.41.40 PM

Getting there!

Let’s check out the console to see what errors we still have…

Screen Shot 2017-07-07 at 3.16.27 PM

Welp. Still a lotta red! Let’s dig back in and tackle some of these errors. Starting with the first error:

Failed to load resource: net::ERR_FILE_NOT_FOUND – conversion.js

So this error is telling us we’re missing a conversion.js file. Going back to our index.html file (or the view page source at carbonfive), we can find that the js file has something to do with Google Analytics. We don’t need analytics for our purposes, so we’re just going to delete that whole script from the head. If you’re following along, the script starts just after the script for app.js and ends just before the closing head tag. Delete it all!

Now when we refresh our local index file in the browser, that error is gone. Our next error is for file:///images/square.png. Looking at this link, right off the bat, there are too many forward slashes after ‘file’. Also, we don’t have this file! If we go into Chrome’s Dev Tools (command + option + j), and go to ‘sources’ we can see the images folder and the images within. If we click and drag an image into its own tab in Chrome, we can see that its hosted on carbonfive. All we have to do is prepend the reference links for all images with ‘http://carbonfive.com&#8217; and we should be good to go. Find the square.png img tag in your index.html file and add it. That should take care of that error.

Looking at most of the other errors, we can find them to be the same in nature. We just have to complete the previous step for all images referenced in the our index.html and app.css files. If you’re using Atom as your text editor, you can click just before the forward slash on the image you want to change. Then hold down the command key do the same to every image you want to change. Now we can change them all at the same time!

After refreshing our local html page in Chrome, there are significantly less errors! Sweet!

Screen Shot 2017-07-07 at 4.01.48 PM

Much better!

Screen Shot 2017-07-07 at 4.04.47 PM

We just kicked those errors asses. The site is really coming along now. Let’s meet back here next week for the third and final installment. Until then, CHEERS:)