Rails, AngularJS (1.5.8), and Webpack — Part 3

Alrighty then. Where were we? I believe we left off in a good place. We installed the webpacker gem, and seemed to have communication between our newly created JS file and our app. Now for the hard part. I’m still learning this stuff myself, so bear with me. We’re going to attempt to use ES6 modules instead of the old way of declaring AngularJS components and such. This style guide is a good starting point to get to know what your components will look like and how they’ll interact with each other.

Setting up the Main Module

The first thing we’ll want to do is setup up our main Angular module in app/javascript/packs/application.js. First we have to import angular into the file so our module knows what it’s attaching itself to. We are also going to export the module, which will allow our webpack to compile it when we run app in the terminal.

// app/javascript/packs/application.js

import angular from 'angular';

const meals = angular.module('meals', [])

export default meals;

Now we have to declare our app in our main html file: app/views/layouts/application.html.erb. So in the body tag, add ng-app=”meals”.

<!DOCTYPE html>
<html>
  <head>
    <title>Meals</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all' %>
    <%= javascript_include_tag 'application' %>
    <%= javascript_pack_tag 'application' %>
  </head>

  <body ng-app="meals">
    <%= yield %>
  </body>
</html>

Now our app knows that it’s an Angular app and it’s looking for a module called ‘meals’. Let’s add a route with a component so we can actually see something working on the Angular side of the world.

Routing With angular-ui-router

If you’ve built anything with Angular in the past, you’ve most definitely used angular-ui-router. We’re going to install it with yarn. If you don’t have yarn installed, check out the installation instructions here. To install, or ‘add’ as it’s called in yarnish, head over to your terminal and type: ‘yarn add angular-ui-router’. If you check your dependencies in your package.json file, you should see ‘angular-ui-router’ listed.

So let’s see if we can get a route working. In our angular_home.html file, let’s add a ui-view directive.

<-- app/views/application/angular_home.html -->

<ui-view></ui-view>

This will give us an entry point into AngularLand and let us declare routes with $stateProvider in a config function. Back in our application.js file, let’s add a config function and a route. First we’ll have to import the ui-router so we can use all of its goodness. Check it…

// app/javascript/packs/application.js

import angular from 'angular';
import uirouter from 'angular-ui-router';

const meals = angular.module('meals', [uirouter])
  .config(($stateProvider) => {
    $stateProvider
      .state('home', {
        url: '/',
        template: `<h1>Hola Mundo!</h1>`
      })
  })

export default meals;

Ok so here we’re importing the angular-ui-router and chaining a config function onto our module. Angular-ui-router gives us access to $stateProvider, $urlRouterProvider, $state, and $stateParams. In the config function above, we’re using the Arrow function syntax now available in ES6, and setting the state. With a url and a simple template, we should be getting somewhere. Let’s quickly make a link back in angular_home.html so we can see our route is working.

<-- app/views/application/angular_home.html -->

<a ui-sref="home">Home</a>
<ui-view></ui-view>

Run the Webpack and Rails Server Simultaneously?

Now to run webpack, we can’t just run the rails server. We actually have to run the rails and the webpack servers. Back in the terminal, create a new tab in the same directory, then run ‘./bin/webpack-dev-server’. This will compile your included javascript files through webpack. If you’re like me, then you probably got a lot of red errors followed by this line: webpack: Failed to compile.

So something is not letting us load our module. If we scroll up in the terminal, we’ll see that most of the errors say that angular doesn’t exist. But I thought we installed Angular already!! Well, I’m pretty sure that when we installed it with the webpacker command, it installed Angular 4. We need version 1.5.8, which we can easily install add with yarn. Exit out of the webpack server in your terminal. Then type ‘yarn add angular@1.5.8’.

Check out your package.json file and you should see angular with the correct version listed under the dependencies. Now if we try to run the server again – ‘./bin/webpack-dev-server’ – everything should compile (there might be a few warnings, but let’s not worry about those). In your other tab run the rails server command and in your browser go to ‘localhost:3000’. You should see a link that says ‘Home’. Click it, and you should be routed to the home route that we set up earlier. If you followed along, you should see ‘Hola Mundo!’ on the webpage!

To Sum it Up

We are in the Angular business now! In this episode, we’ve connected the front end to our meals app with webpack, added angular-ui-router and AngularJS, created our main module with a route and template, learned how to run the webpack server, and saw our template working in the browser. Next time, we’ll get some functionality going with some http requests to the backend and do something a little more exciting than Hello World Hola Mundo. As always, thanks for reading. I hope this helps someone out there! Until next time…CHEERS:)

Advertisements

Removing whitespace from a string in Ruby vs. JavaScript

I’m back from vacation. After visiting my family in Long Island, we ventured up to the Catskills for a few nights, which culminated with my younger sister getting married. It was a very cool wedding! The next day, my wife, nephew, and I drove up to Montreal to see her folks. Montreal is one of my favorite cities (in the summer) – it has very European feel. As great as it is to get away, it’s always hard to get back into the groove after a trip. I’m just getting my sea legs back under me so this post is going to be short and sweet.

Have you ever needed to get rid of leading and trailing whitespace from a string? It’s a good rule of thumb to do just that to any input you’re receiving on a form. Luckily, it’s quite easy in most languages. Let’s take a look at how we’ll approach this in Ruby first.

str = "  How's it going?   "
=> "  How's it going?   "
# Let's get rid of that whitespace
str.strip()  
=> "How's it going?"
str 
=> "  How's it going?   "
# We didn't permanently change the string itself
# Most methods are non-destructive, but Ruby let's us be destructive if we 
# really want to. We just got to bang it (pun intended)
str.strip!() 
"How's it going?"
str 
=> "How's it going?"

Pretty simple! Let’s take a look at how to do this in JavaScript.

let str = "  How's it going?   ";
str.trim(); 
'How/'s it going?'
str  
'   How\'s it going?   '
// There's no permanent destructive way to change strings in JavaScript - they 
// are immutable. So we just have to reassign our variable like so...
str = str.trim();
'How\'s it going?'
str  
'How\'s it going?'

I mentioned that strings in JavaScript are immutable. This means the string cannot be changed in memory. So when we call a method like trim or slice on a string, the return value is a new string. Like the example above, we have to reassign ‘str’ to the return value of the method call. In Ruby however, strings are mutable. Let’s take a look.

str = "  Trim me  "
str.object_id 
=> 70365544319940 
str.strip!()
=> "Trim me"
str.object_id
=> 70365544319940 
# Even though we changed the string, the id is still the same
# We can also change characters in place, which cannot be done in JS
str[7] = '!'
=> '!'
str
=> "Trim me!"
# Pretty cool!
str.object_id
=> 70365544319940 
# No change

That’s it for this week. Always remember how cool Ruby can be. It makes life easier in many ways. JavaScript however, can do much more. It is not only an Object Oriented language, but a multi-paradigm language! From Wikipedia:

As a multi-paradigm language, JavaScript supports event-driven, functional, and imperative (including object-oriented and prototype-based) programming styles. It has an API for working with text, arrays, dates, regular expressions, and basic manipulation of the DOM, but does not include any I/O, such as networking, storage, or graphics facilities, relying for these upon the host environment in which it is embedded.

Thanks Wikipedia! Until next time! Cheers:)

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

Ever want to copy a website? Well, it’s pretty easy – especially with Chrome’s Dev Tools! I find it pretty useful to go into someone else’s code to see how they’re doing what they’re doing. Then you can implement new cool features for sites you’re working on. I’m not going into complicated websites with API’s and the like; just a simple static site.

I’m going to be using Carbon Five’s website as reference. First head on over there, then right click on the page and select ‘view page source’. This will show us all the html for the page. Now just select all (command + ‘a’) and copy. In your text editor of choice (I’m using Atom), create an index.html file and paste the html there. You’ll see a bunch of files that are referenced in the ‘head’ of the document. We’ll have to copy the non-CDN local files into our text editor.

We’re going to open each file from the page source and copy file into our text editor.

Screen Shot 2017-07-02 at 3.41.31 PM

Create folders for each type of file, ie. javascripts, stylesheets, images, etc. We’re going to do what we did above when copying and pasting all of the HTML. Starting from the ‘javascripts/showup.js’ file in the head of the view source page document, click on each file, select all, copy (noticing a trend?) and paste into a newly created file in Atom. Name the file the same as the file you’re copying from. From here, let’s see where we stand by opening the index.html file in Chrome. Go ahead, I’ll wait…

Screen Shot 2017-07-02 at 5.24.47 PM

It should look something like this

Woah! All of a sudden we’re in 1995 and Nirvana’s on the radio! We’re getting the bare bones HTML here. Let’s take a look in the console to see what’s going on under the hood. Command + option + ‘j’ will get us there. Notice all of the errors.

Screen Shot 2017-07-02 at 5.30.38 PM

That’s a lotta red

There are a ton of files that can’t be found. There are definitely some files we haven’t looked at yet, but let’s focus on the ones we have. Our file directory must be different than Carbon Five’s. All we have to do is reference them a bit differently than we are.

Let’s look at the non-CDN files in the ‘head’ of our index.html page. They all start with a forward slash, but if we’re referencing from the index.html file, we’ll have to prepend them with a single period to jump up to the root directory. Start from the ‘showup.js’ file start adding.

<script type="text/javascript" src="/javascripts/showup.js"></script> // This
// Turns into 
<script type="text/javascript" src="./javascripts/showup.js"></script>

When you’re done (remember to save), refresh your index.html file in Chrome. You’ll notice a few things happened. The page has some styling now – not great, but it’s something. Next, we have less errors in the console. Sweet! Let’s keep going and turn these errors green.

In the console, notice how the cdn files which can’t be found start with two forward slashes. Since they are referencing outside websites as opposed to local files, we’ll have to prepend them with ‘https:’, and they should be good to go. Back in our index.html file, let’s do just that. Once you’re done, notice how the links turn blue. We now have good links. Go back to your browser and refresh.

Screen Shot 2017-07-02 at 5.41.40 PM

Getting there!

Now we’re talking! Since we’re now referencing the bootstrap cdn files correctly, we have our navbar looking good and the page layout is looking much better. Next time, we’ll add images and conquer any other errors we come across. Until then, CHEERS:)

I’ve Got 99 Problems – but Deploying My Rails/Angular App to Heroku is No Longer One of Them:) PART 2

So where was I? Oh yeah, I left off at changing my problem js file extensions to ‘.es6’ so there would be no problem with new JS6 syntax. This definitely helped, but in it’s place sprung another problem. Only the images that were not hooked up to the database on my site were showing . So I used my noggin and realized that I never migrated my database to Heroku! DOH!

When I tried to run ‘heroku run rake db:migrate’, the migration kept aborting with this message:

PG::UndefinedTable: ERROR:  relation "users" does not exist

I definitely had a table called “users” so that didn’t make much sense. I did a little digging and found out that postgres (the database Heroku uses) does not like tables relating to other tables that have not been created yet. The table being created was referencing a table that was created on a later migration. I know it’s not a good idea to mess with the names of migration files, but I did anyway. Rails timestamps migration files, so I just had to change my “users” file timestamp to a date before the file in question.

So I tried the migrate command again and got the same error. Strange. My migration files had quite a few additions which later became subtractions. I decided that I only really needed three migrations for three tables. Since I had a good seed file which could recreate everything I needed, I decided to recreate only the migrations I needed. This would allow me to reset the database and start from scratch. I deleted the schema and development.sqlite3 files so there would be no references to the old migrations. Now I could recreate my database and schema file.

$ rails db:drop db:create db:migrate db:seed
// This will delete the entire database, losing all data
// recreate a new database and runs the migrations
// db:seed will seed the database from seeds.rb

I had a brand spanking new schema and database, ran my local server and everything was running smoothly. So I ran the heroku migration command again and got THE SAME ERROR!! WTF?!? After googling for a bit, it hit me. I didn’t push the new changes to heroku! Often times it is the simple tasks that one might forget to do that causes errors. Note to self: if you are banging your head against the wall, stop for a minute and think of the steps you would normally take. Save yourself some time and energy. The first change to the “users” migration file name probably would have worked if I just slowed down a little.

After trying to migrate to Heroku again, it worked! Now my site is up and running, and I’m feeling good! Hopefully this helps fellow programmers out there that get stuck – and have sore heads! As always, thanks for reading!

Adding a Gradient to a Background Image with CSS

I’ve been building a portfolio site for myself and came across a small problem. I wanted the navbar to be transparent on the hero part of the page, however, the text in the navbar wasn’t showing up very well with the background image that I was using. Take a look…

Portfolio-site screengrab

Background image without gradient at top

Notice the navbar text. Not very clear if you ask me. What to do? If I had a bit of gradient at the top, that would let the text pop more. Of course I could use Photoshop to transform the image, but being a developer, I wanted to do it with code. It turned out I could accomplish what I wanted with CSS. I have to admit, even though I’m a Full Stack Developer, CSS has never been my thing. But I have to say it’s been growing on me lately. The CSS for my background image looked like this:

.background {
  background-repeat:no-repeat;
  background-position:50% 50%;
  background-image: url('../images/road-trees.jpg');
}

Pretty simple. The color of gradient at the top of the image should be within the image that I was working with. I found a cool extension for Chrome called ColorPick Eye Dropper that gives you a color picker that you can use for whatever website you’re on. I used this to find a nice dark green in my image. The CSS is quite simple. You just have to add a linear gradient to the background image styling like so.

.background {
  background-repeat:no-repeat;
  background-position:50% 50%;
  background-image: linear-gradient(
      rgba(18, 39, 32, 0.9),
      rgba(255, 255, 255, 0)
    ),url('../images/road-trees.jpg');
}

The first value of the linear-gradient represents the top of the image and the second, you guessed it, is the bottom. The last value of the rgba is the opacity. As you can see, the second value is white with an opacity of 0, which makes it transparent. This gives us the final product.

TJ portfolio hero

Image with CSS gradient at top

I’m not a designer, but I know that looks better. Everything is popping nicely. Happy coding:)

The Big O

First off, this is a technical blog. My apologies if you came here looking for something a little sexier. Not that Big O Notation can’t be sexy. Depends on what floats your boat or sinks your battleship. Anywho, the following is a little teaser on Big O.

Foreplay

When you take your first few steps learning how to program, something like Big O Notation is the furthest thing from your mind. Learning to code is hard. Period. There is so much to know, and quite frankly, it is daunting. Imagine looking up at the highest peaks of Mt. Everest from the bottom of the mountain. Now imagine that the mountain is always shifting and getting bigger. That’s what it feels like when you start learning. Somewhere along the way (hopefully), your footing will become more secure on the shifting ground and you’ll gain some comfortability in the place of not knowing. Because nobody knows it all. Keep one foot in front of the other and keep climbing. Try to enjoy the ride.

If you went to a bootcamp, there was so much knowledge being pushed into your brain in a few short months. Bootcamps are great, but they just focus on web development. When you graduate and start to prepare for interviews, you begin to hear scary terms that you never heard before. Things like Linked Lists, Big O Notation, Bitwise Operators, Binary Trees, Stacks, Queues, etc. These are all computer science topics and good to know, but unless you are working on high level stuff, you probably don’t have to know all of them. But those pesky interviewers will probably test you on them because they know most bootcamps don’t teach it and because they had to learn it when they got their BS in CS.

Heavy Petting

One of those terms, Big O Notation, is actually very useful to know. When you begin to program, you’re not thinking about how your program will scale if a few thousand or perhaps a million people start to use it. You just learn what a for loop is, then learn you can have nested for loops, and you think everything is grand! Not so fast Kemosabe. This is where Big O Notation and scaling come in. Let’s take a look at how you might write a function to double each element in an array of arrays.


function doubleMe(arrayOfArrays) {
  const doubledArrayOfArrays = [];

  for (let i = 0; i < arrayOfArrays.length; i++) {
    let placeholderArray = []
    for (let j = 0; j < arrayOfArrays[i].length; j++) {
      placeholderArray.push(arrayOfArrays[i][j] * 2);
    }
    doubledArrayOfArrays.push(placeholderArray)
  }

 return doubledArrayOfArrays;
}

doubleMe([[1,2,3], [4,5,6], [7,8,9]];  // [[2,4,6], [8,10,12], [14,16,18]]

This might look all fine and dandy, and when you first learn about nested for loops they might seem like the best thing since sliced bread! But let’s take a look at how this will scale.

We Have Lift Off

The length or size of our arrayOfArrays above is 3. However, since each element of the array is another array the function has to work that much more. Basically, for every item in the array (n for the input size), we have to do n more operations. So n * n == n^2 or O(n^2). The given example might be a little too on the nose being 3^2 is 9. It’s usually not that exact. You might ask, ‘So what’s the big deal? The function only has to run 9 times instead of 3’. Well, everything is groovy if the input is low, but what if it grows to 100 or 1,000 or 1,000,000. You start to get the point. With lower inputs, it’s not a big deal, but as the input grows, so does the time complexity of the function.

BigOn2

Weeeeeeeeeeeeeeeee!!!!

I’m Very Sensitive

Sorry if I got a little too excited. Let’s back up here a bit. Maybe I should start with O(1). Gayle Laakmann McDowell, author of a Cracking the Coding Interview, has a great video about Big O. It’s definitely worth a watch. She gives a great example about a problem South African programmers were having. Their internet connection was super slow and it was taking a long time to transfer data to team members in a different city. So they tried an experiment. They transferred the data to a usb drive and had a carrier pigeon (let’s call him Bob) deliver it to their work mates in the other city. At the same time they were transferring the data through their internet connection. The race between Bob and the internet. Guess who won?

If you said ‘BOB!’, then you are correct. So what does this have to do with Big O? Glad you asked! Bob’s flight in Big O terms is O(1). If it took Bob 30 minutes to get from one office to the other, then no matter what size the file is, it does not change the amount of time it takes him. Whether he’s flying with 10MB or 1TB, it still takes him 30 minutes. So O(1) is a program or function that takes the same amount of time to run no matter how large the input grows.

Time_Complexity

Bob is a low flying bird

Almost There

Revisiting our South African friends, as the size of the data they were transferring (over the internet) grew, the time it took to transfer grew by the same order. This would be O(n) and is linear in time and space. The green line in the graph above represents this. What would this look like as a function? Take my hand and let us find out.


function tripleMe(array) {
  const tripledArray = [];

  for (let i = 0; i < array.length; i++) {
    tripledArray.push(array[i] * 3);
  }

  return tripledArray;
}

tripleMe([1,2,3,4,5]);   // [3,6,9,12,15]

Each element of the array gets worked on once. If our array had 1,000,000 elements, our for loop would run 1,000,000 times. From an input of an array of 1 element to an input of an array with 1,000,000 elements, the time complexity a straight line.

Pillow Talk

There are definitely other elements of Big O to talk about and understand, but I’m spent. I gave a pretty good (in my humble opinion) performance overview of the basics. I hope it was as good for you as it was for me. Sweet dreams buttercup.

Off the Rails

Learning RoR has been quite challenging to say the least. Add in the personal grief that I’ve been going through for the past few months and I can say it has been one of the hardest things I’ve ever had to do. I was keeping a good pace through June and was nearing the final assessment for the Rails section of the course when I had to do some self-assessing. I realized that even though I was getting through the material, not much of it was sticking. I thought it would be a good idea to take a bit of time off (which the good people at Flatiron allowed me to do) and review. So I took about 6 weeks off and did just that. I came back feeling strong and ready to code.

I thought I would stay with the theme that I started with using Sinatra, which was a Produce App. It basically keeps track of produce that you have in your fridge and lets you know how many days left until spoilage (because finding rotten fruit in the back of the fridge is the worst!). Pretty simple right? Well I ran into some trouble because I didn’t fully understand all of the instructions. Maybe I should rephrase that. I understood the instructions, but jumped in the deep end without making sure there was water in the pool. Although in the end, I learned a ton and feel much more confident in my abilities and understanding of programming and debugging.

So back to the part about jumping in the deep end. Well, it turns out that a little more thinking is involved in an app creation before any actual coding is done. Of course you can always add another column to a table in your database. Or in my case a whole new table itself. It worked this time, but I know in the future I will have to do a little more thinking before I start coding. The initial design of my app was very basic:

  • users table with columns:
    • name
    • email
    • password
  • produce table with columns:
    • name
    • type (fruit or veggie)
    • shelf life (integer)
    • description/benefits
  • users_produce joins table with columns:
    • user_id (foreign key)
    • produce_id (foreign key)
    • created_at (date)
    • eaten? – a boolean value, set to false as default and turned to true if it was taken out of the fridge.

The joins table would have a method to calculate how many days left until expiration. This is accomplished by calculating the difference between the created_at value of the user_produce and Time.now and subtracting that value from the shelf_life value from the produce. Looks something like this:

screen-shot-2016-10-12-at-10-32-03-am

I added some nice bootstrap styling, a Devise authentication system, and had a working app pretty quickly. Then I went back and re-read the instructions. One of the trickiest parts of Rails is nested attributes and my current configuration left me no way to implement this feature. Back to the drawing board. I needed the ability when creating a new ‘something’ in one table, it would also cause the nested attributes to create a new ‘other something’ in another table. I know that is super technical and will go over most heads. I do apologize. So I thought about it. And thought some more. I needed another table that could associate with my produce table. I would have to expand my app.

I decided on a Juices table with just a name column and a JuiceProduce joins table with produce_id, juice_id, and quantity columns. This would enable the user to create a new produce item by way of nested attributes from the creation of a new juice. Cool. Implementation was quite difficult and I would be lying if I said it didn’t take me a few days. It seems like it’s always these sticking points where high frustration ends in the most learning. Lesson to self: don’t get so frustrated…there is an answer and it will make you learn! You just have to keep moving forward and ‘get your hands dirty’. That’s what I like to call prying. Sometimes I’ll put a binding pry after each line of code in my controller action and in the instance method in my model. Here I can see exactly what is going on after each line of code. I likey. It feels like I’m getting my hands dirty:)

I made it a lot harder on myself by having dropdowns for produce (which were already in the database) to choose from in the New Juice form, while also having input fields for new produce (which was not in the database). But like I said earlier, it’s these sticking points that really challenge you and end up speeding up the learning process by leaps and bounds. I’m proud of myself for sticking with it and have a new found confidence that I’m actually going to be a web developer…and a good one too! Check it out in action!