puzzle pieces

So I’m banging away at my jQuery project. I got hung up on some code tonight but got it working right before I stopped for the night! I was stoked! So what was I stuck on? In my app a user can create as many places as they want. Each place can have as many items as they want. A user can look at a specific item and see the name of it, the rating they gave it, any notes they wrote about it and where the item is available (the places they’ve added it to). I wanted to implement a “Next Item” button/link that when clicked will load the next item for the current user.

First things first I needed an array of the current users item ID #’s. I needed this because my show pages follow RESTful conventions and use the item ID in the URL. This is what the show page is expecting in its params. So I got that done relatively easily:

let itemsValues

$(() => {
  $.getJSON('/items.json', function (data) {
    itemsValues = $.map(data, function (e) {
      return e.id
    })
  })
})

Then, I wanted the functionality that I stated above. However, I didn’t want to get to the last item and just have a button that does nothing because there’s no next item. I also didn’t want the button to just disappear (I did that and I thought it was weird). So I decided when we reached the last item we should loop back around and go to the first item again. So I started coding and got to this point:

$('.js-next').on('click', function() {
  let nextIndex = itemsValues.indexOf(parseInt($('.js-next').attr('data-id'))) + 1
  $.getJSON('/items/' + itemsValues[nextIndex], function(data) {
    $('#name').html(data['name'])
    $('#rating').html(data['rating'])
    $('#notes').html(data['notes'])
    if (nextIndex === itemsValues.length)
      $('.js-next').attr('data-id', itemsValues[0])
    else
      $('.js-next').attr('data-id', data['id'])
  })
})

So my “Next Item” link has a class of ‘js-next’. Then I set a nextIndex variable by getting the current data-id of my link (ie, the current item being displayed ID number), turning that into an integer, finding the index of that ID in the itemsValues array and adding one to it. Then I call my internal API and get the next item’s info as a JSON object. I then fill in the new data to the DOM. Finally, I have an if…else block where I try and set the data-id to the first item ID if the new item is the last item in the array. If not, set it to the now current item ID.

Looking at this now I think the logic is flawed because I increment by one on the API call after the click. So setting it to the first item before the click will eliminate one item from ever showing up. I actually had this happen and couldn’t figure out why. This logic was fuzzy but is probably why I ended up moving the if…else logic to the top of my function and when I did it worked!

$('.js-next').on('click', function() {
  let nextIndex
  let dataIdIndex = itemsValues.indexOf(parseInt($('.js-next').attr('data-id')))
  if (dataIdIndex === itemsValues.length - 1)
    nextIndex = 0
  else
    nextIndex = dataIdIndex + 1
  $.getJSON('/items/' + itemsValues[nextIndex], function(data) {
    $('#name').html(`${data['name']} -
        <a href="/items/${data['id']}/edit">Edit</a> -
        <a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/items/${data['id']}">Delete</a>`)
    $('#rating').html(`Rating: ${data['rating']}`)
    $('#notes').html(`Notes: ${data['notes']}`)
    $('.js-next').attr('data-id', data['id'])
  })
})

I also filled out the HTML for the name section of the page using those lovely template literals I talked about in my last blog post. This project is coming along well. I’m hoping to be done with it tomorrow night at some point in time. If I can finish this off before the weekend I’ll be super happy and think right on track to be done before the end of the month.

Time spent today: 2:16
Time spent total: 394:16
Lessons completed today: 0
Lessons completed total: 646

I’ve been moving along as of late. Today I was able to knock out my Tic-Tac-Toe in jQuery project. Well, it’ll be done VERY soon. I paired with another student Henno who’s in a time zone 7 hours ahead of mine. I had just started and he was looking for a partner so while he read up on the project and had a bit I got the first three controller tests to pass. I did hit an issue though where my active_model_serialiers gem was the most up to date version and that was causing an issue with what the test wanted returned. I was missing the root key of the JSON. With some help, I decided to roll back the gem version and got the test passing. Then we paired for a solid 5 hours before he needed to get some rest. We had 9 tests still failing. Decided that I’d do 4 or 5 of the last 9 and he’d finish it up. So that’s where the project is right now but I know he’ll get it done tomorrow. There isn’t much left.

It was a good exercise on pairing. We set up a GitHub repo and added a collaborator then discussed what our next test was and how to approach it. Sometimes one of us would just go for it and code it. Sometimes we’d both go at it and whoever got it first would push it up. Henno was using git stash to get rid of any WIP he had and clone down the fresh updated code. I used that a couple times as well. I had heard of stashing but never done it. I know the code is still around somewhere.

I started work on my Rails App with a jQuery Front End tonight. I actually got a good ways into it. I’m getting more comfortable with jQuery and that’s helping a lot. I’m also learning some better patterns with respect to the DOM and how to work with and manipulate it. My jQuery project is a refactor of my Rails Portfolio Project. For example, I’m taking a show view that lists the items rated at a specific place and rendering those items via jQuery from a JSON call to the back end. The serializer makes creating the JSON objects so easy. ES6 Template Literals make writing multi-line HTML strings with embedded placeholders a lot easier than using concatenation or newline slashes.

// With ES6 Template Literals
data.items.forEach(function (item) {
  itemList = itemList.add(`<li><strong><a href='/items/${item['id']}'>${item['name']}</a></strong>
    <ul>
      <li>Rating: ${item['rating']}</li>
      <li>Notes: ${item['notes']}</li>
    </ul>`
  )
})

// With newline slashes
data.items.forEach(function (item) {
  itemList = itemList.add('<li><strong><a href="/items/' + item['id'] + '">' + item['name'] + '</a></strong> \
    <ul> \
      <li>Rating: ' + item['rating'] + '</li> \
      <li>Notes: ' + item['notes'] + '</li> \
    </ul>'
  )
})

// Concatenation
data.items.forEach(function (item) {
  itemList = itemList.add('<li><strong><a href="/items/' + item['id'] + '">' + item['name'] + '</a></strong>' +
    '<ul>' +
      '<li>Rating: ' + item['rating'] + '</li>' +
      '<li>Notes: ' + item['notes'] + '</li>' +
    '</ul>'
  )
})

So yeah, I’m happy about Template Literals. I’m also happy that since I’m only writing Front-End, for the most part, I think this project will go relatively quickly. I spent 90 minutes on it tonight and knocked out a couple of the specs. A decent amount of time was spent setting the project up then getting rid of the turbolinks gem when it broke my app. I decided to get rid of it completely rather than just figure out a workaround because my app isn’t robust enough to truly benefit from all that turbolinks does in my humble opinion. I also remembered other students further along saying the first thing they did after a certain point was remove turbolinks when they were working on projects. It’s looking like I’ll be starting to learn React this weekend and be even that much closer to graduation!

Henno and I committed to putting in some serious work and getting done before the end of the month and both of our next tuition payments come out. We’ll see how well we do and if we help keep each other accountable.

Time spent today: 9:15
Time spent total: 391:22
Lessons completed today: 1
Lessons completed total: 642

So I’m pulling back from my daily blog unless I have code to write about. I can concentrate on school and extra 30 mins to an hour per day if I don’t write. Here’s something interesting I’m pondering and haven’t tested yet. I’m not really sure why I haven’t tested it but…

// To ensure JS is loaded after the page loads
$(document).ready(function () {

})

// Better way to do the same
$(function () {

})

// Does this work?
$(() => {

})

Time spent today: 1:54
Time spent total: 374:10
Lessons completed today: 5
Lessons completed total: 629

I’ve reached the 100-day mark. I have to say, I honestly thought I’d be done by now. I’m 82% of the way there. It’s going to be a mad dash to the end. I really, really, really don’t want to pay another full month’s tuition when I finish a few days into that billing cycle. So it’s pretty simple. I have to finish by June 27th. We’ll see what happens. I have a backup plan if I’m literally working on my final project and I’m sure I’m not going to make it. We’ll see if it comes to that or not…

Tonight had me learning about workers in Rails apps and specifically the Sidekiq gem. It’s pretty sweet how easily it can abstract out letting a task run in the background so a user can keep on with their work. The example in the lesson is loading a large CSV of leads into your web app. First, you create a worker file in app/workers, make sure that file has include Sidekiq::Worker, then take the long-running process and input that into #perform.

# app/workers/leads_worker.rb

class LeadsWorker
  require 'csv'
  include Sidekiq::Worker

  def perform(leads_file)
    CSV.foreach(leads_file, headers: true) do |lead|
      Customer.create(email: lead[0], first_name: lead[1], last_name: lead[2])
    end
  end
end

After that replace the long-running process code in your controller by running the worker.

# app/controllers/customers_controller.rb
class CustomersController < ApplicationController

  def index
    @customers = Customer.all
  end

  def upload
    LeadsWorker.perform_async(params[:leads].path)
    redirect_to customers_path
  end
end

Now if you upload a large CSV file via the form at /customers, when you submit it everything will move along. Then as you refresh the index page /customers it will have a growing list until the CSV file is done being imported into the DB.

I also did a few lessons on Consuming APIs. Luckily for me, this is not completely new to me so I have a good base to work off of. Actually, this shouldn’t be completely new to anyone in the program as earlier labs deal with pulling API data and rendering it to the DOM. My main note on APIs is the querystring which trips me up sometimes.

  • ? after the URL
  • param=value&param2=value
  • ie. https://api.example.com/places?name=tonys&city=nashville

Although, I also learned how Postman has a params section with key/value pairs which helps with building out the query string.

Time spent today: 1:53
Time spent total: 369:58
Lessons completed today: 7
Lessons completed total: 621

Not much to report today. I spent my time working through some labs that were about popular Ruby Gems and how to find good ones. Paperclip, Kaminari, and Active Admin were presented and gone over. I also found out that RubyMine is going to be my IDE basically for the rest of the curriculum. This is because I’m writing Rails backend and JS front end. WebStorm is a 100% JS IDE so it would have serious problems with the Rails part of the apps I’ll be building. When I implement Node, later on, I should use WebStorm.

Other than that I just did some more reading in the Career Prep track. I’m trying to get ahead of the curve on that aspect. I’m debating if I should follow up with the business cards I received this weekend. As part of my career search requirements, I have to reach out to 8 people per week. I could include these connections in that first week. Although, I think prompt follow up is better so I’ll probably schedule some e-mails to go out first thing in the morning.

I also passed 80% done in the program tonight.

Time spent today: 2:13
Time spent total: 368:05
Lessons completed today: 7
Lessons completed total: 614

I finally got back into the swing of Flatiron. I did <30 mins of school yesterday so I just chose to blog about FCC. A lot of reading going on as of late. The Rails asset pipeline and how to use it. I actually figured out some of this since I implemented Bootstrap in my Rails Portfolio Project. It felt good to plow through some labs tonight. I’m so close. Now is the time to crank up the intensity and really go at it to the finish line.

I have to say, I don’t know much about other backends but the asset pipeline is a pretty neat feature of Rails. I guess being such a mature framework has its benefits.

Time spent today: 3:06
Time spent total: 365:41
Lessons completed today: 15
Lessons completed total: 607

dave & seth @ music city code

We had our June meetup today and it was good. A small group but we solved some problems together and we talked shop some. Specifically, Leland brought up the scope of the projects. How it’s easy to go off on tangents and hours later be so far away from what you initially started working on. We shared some tips on how to stay focused and keep within the scope of the project. Especially since a lot of the time, we’ll learn things after we complete a project that just makes it even easier to implement what we truly wanted to do. So sometimes it’s more frustrating to succeed in going the extra mile trudging through the dirt only to realize that you didn’t know about the free shuttle that could’ve gotten you there much quicker and easier.

We put our heads together and helped Andy with a checkbox problem he was having. We were calling checked (MDN, W3Schools) to return true or false and it was throwing an error complaining about not being able to be called on null.

We discussed the job landscape at length as Phillip is on the prowl hard but doesn’t have that 1-3 years professional experience it seems like all Jr. Developer roles are looking for these days. Which we all agreed is a Catch-22 that just doesn’t make sense. Networking is a big key to getting the first job in this industry it seems. Having a Sr. Developer who can vouch for your skills is typically needed for a company to take the leap and risk it. HackerRank came up in the discussion as well as the usefulness of some recruiters to open doors when the resume is lacking.

We found out about CHINGU from Matt. An interesting project that looks to throw people who are self-learning web development into cohorts of like-minded people to level themselves up in a quicker fashion. I was able to find the “Welcome” doc they send to new cohorts and it’s an interesting framework. I’d be interested to see how one actually is executed but don’t think I want to take part in one at this point in time. I have enough going on. It’s a solid option for others though to look at how they can speed up their progress.

I shared some of the resources that we came into contact with this weekend with Music City Code. Specifically, Technologist Federation of Nashville aka TechFed. They’ve got an awesome thing going on. I highly encourage everyone to sign up with them on their site. If you’re looking to get more involved with the Nashville tech scene then volunteer at tech events. The networking is invaluable. Also, the Complete Developer Podcast are a couple, cool dudes. They run a weekly podcast as well as a bi-monthly (that means twice a month right?) developer meetup. Subscribe and go check out their meetup.

We’re looking forward to bigger things for freeCodeCamp Nashville. We’ve got a bigger meeting space in the works. Also, possibly some sponsorships that’ll allow us to do more and maintain a small budget. We received a lot of positive feedback from Music City Code attendees who stopped by the table. We also found out that Nashville Software School shares freeCodeCamp as a resource for people wanting to learn more about coding.

Finally, a huge CONGRATS to our very own Organizer Dave who landed his first dev gig this weekend! Yet another one showing the people can make the transition to web development without a CS degree and without attending a boot camp. Persistence and hard work do pay off.