The Odin Project – Etch A Sketch

This is the project I’ve most recently completed as part of the Odin Project’s full stack JavaScript path. It was actually fun, perhaps because it’s kind of like a game.

I’m definitely not qualified to write a JavaScript tutorial but I’ll give you an overview of how I completed this project. The requirements are listed here.

CSS Grid

I began by creating the grid itself. I used CSS Grid, though there are other ways it can be done according to the project page. Initially the grid was set to 16 x 16 squares. In my HTML file I made a div with the id ‘grid’. Then in my JavaScript file I put it into a variable like this:

const grid = document.querySelector("#grid");

I used CSS to set the display to ‘grid’ and set a width and height.

Then I created a function that set the gridTemplateRows and gridTemplateColumns to repeat 16 times and take up ‘1fr’ of space. ‘1fr’ here means 1 fraction of the available space. So – as far as I know – if all parts are equal to ‘1fr’ then they will always be equal no matter how many there are. I knew this would be important for later when variable rows and columns needed to be accounted for.

This function then runs a for loop for the area of the grid. This is what makes the actual grid items. Each time it runs through it creates a div, gives it the class ‘gridBox’ and adds it to the grid. The loop looks like this:

for (let i = 0; i < size * size; i++) {
    let div = document.createElement("div");
    div.classList.add("gridBox");
    grid.appendChild(div);

Adding An Event Listener

The class ‘gridBox’ is used to create an event listener for every grid square, so that whenever the mouse goes over a square, it changes the color. This is done by adding a class to the classList; this class simply sets the background color to a pretty purple/magenta gradient. Here’s my event listener code:

gridBoxes = document.querySelectorAll(".gridBox");
gridBoxes.forEach((gridBox) => {
    gridBox.addEventListener("mouseover", (e) => {
        gridBox.classList.add("active");
    });
});

I did try changing the classList.add to classList.toggle so that if you went over the same square again it would remove the color, but I decided I liked it better this way.

Finishing Touches

Once I had the 16 x 16 grid working, it was fairly simple to make the size a number chosen by the user. Upon loading the page the user is asked the number of columns/rows they would like and then this number is stored in a variable, which is used to generate the grid.

Initially I just had a reset button which asked the user how many boxes they wanted this time and cleared the grid. But then my husband was like, “why can’t you just have a reset button that clears the grid and lets you keep the same size and add another button for changing the size?” This was simple enough to do so I added the other button to appease him.

Final Project

You can view my Etch A Sketch on GitHub pages here and the code is here. It’s not fancy but it works! I should mention that I know the grid itself does not resize so if your screen is small then you may have to scroll. This was something I did play with but I was having trouble making the variable rows/columns work properly with a responsive box. It wasn’t in the project description as a requirement so I left it as it is.

I’d also advise you not to choose a crazy number for the size. I think I put in 400 once and my browser couldn’t handle it. 100 is a pretty safe upper limit.

Please don’t think this is an example of good code either; I don’t think it’s bad but it’s likely not optimal.

I’m currently still working through the freeCodeCamp JavaScript section. Soon I’ll be up to the projects and then I can post about it!

The Odin Project – JavaScript Track

I’m very pleased with myself for thinking of a better title than simply ‘JavaScript Sucks’. I’ll likely have to use that one at some point, so at least now I still can. JavaScript just tends to drive me nuts. I don’t like the syntax. I feel like I always have a zillion closing brackets to keep track of and I get confused. And arrow functions are often hard to read. Or maybe I’m just dumb.

However, I actually did something reasonably fun today with JavaScript (on a beginner level; don’t get excited).

I’ve spent some time the last few days trying to improve my JavaScript because I suck at it. It’s also probably closer to what I ‘should’ be working on, since I don’t think Django is used at the place I might get a job. I’m definitely not done with Django, because I like it, and may need it after all if I fail and have to go looking for a job somewhere else. But it was time for a little break.

As I mentioned in my last post, the Odin Project has recently released a full stack JavaScript curriculum. Originally they only had a Ruby based track, which people say is very good, but I wasn’t interested in learning Ruby so I didn’t bother looking. Now I’m finally checking it out since I can always use some more help trying to learn the dreaded JavaScript. One really big bonus here is that all the content is completely free. I love free stuff.

The JavaScript track is split into five sections:

  • Web Development 101
  • JavaScript
  • HTML & CSS
  • Node.js
  • Getting Hired

For those interested, the Ruby track has a similar layout:

  • Web Development 101
  • Ruby Programming
  • Databases
  • Ruby on Rails
  • HTML & CSS
  • JavaScript
  • Getting Hired

I’m currently in the Web Development 101 section of the JavaScript track. It covers basic HTML, CSS and JavaScript, and how to use Git. It also takes you through setting up Ruby. This probably should be removed because who wants to go through all that when they aren’t planning on using it? As a Windows user, they were recommending I set up a virtual machine for installing Ruby, so I just skipped over all that stuff. I can see what they’ve done – the only actual new content is probably the Node.js section, the others are all just the same as their Ruby track. That’s fine but they should edit where required to keep the content relevant.

I skimmed over the non-JavaScript stuff so far since I didn’t need to study HTML, CSS or Git. From what I can see though, this is a great resource. There are explanations and exercises on the Odin Project’s website itself, as well as a bunch of projects, but there are also lots of links to other free resources that are meant to supplement the content provided.

I’ve been working through the JavaScript parts of the Web Development 101 section. I had to make a rock, paper, scissors game that ran in the console, and then I did a bunch of exercises and didn’t struggle too badly with them, so that was pretty cool. I did, however, get frustrated a few times with how awkward it was to do some things that are easy in Python.

Today I completed the next project which was to take the rock, paper, scissors game and put it into an actual web page. I sighed, as I usually do when faced with doing a bunch of JavaScript, and began. I did finish, but my code is horrible. I have this gigantic block of if statements. And a bunch of global variables. It’s probably twice as long as it should be. But it works!

I did cheat a little though. I have yes/no buttons that are hidden initially and then show up when you finish so that you can indicate whether or not you want to play again. When I try to add the class that hides them after the player selects ‘yes’, it can’t seem to see the global variable that I set for the element here:

const again = document.querySelector("#reset");

That exact same variable is accessed just fine by other functions using this:

again.classList.toggle("hidden");

Just not by my reset one. And yeah, I know what you’re probably thinking. What kind of variable name is ‘again’ anyway? Probably not a very good one. I ended up making it work by doing this instead of using the variable:

document.querySelector("#reset").classList.toggle("hidden");

This bothers me though. Obviously I’m doing something wrong. I’ll go back and refactor this, probably, and hopefully discover what the problem is.

If you want to see my code I’ll show you the Github link but otherwise I am not posting it on here because it’s so bad it’s embarrassing. Not only is the code messy but the web page isn’t very pretty either since I just don’t care a lot about front end stuff. I think it would be more beneficial for me to move on at this point then spend a bunch of time refactoring though, so I’m going to start work on the next project which is an Etch-A-Sketch. I have to admit that although I don’t like JavaScript, I do like making games, even if they are small and silly, so I’m glad that the projects have been games so far.

It’s getting to be about time to set up a job interview, but I’m scared. I’m worried about failing the technical test. I’m also not really a people person so I may just do something else wrong. But I guess I have to at least try.

I hope all you US people are having a great 4th of July. We’re celebrating by eating pizza because pizza is awesome.

Doing Things the ‘Right’ Way and Learning Frustration

I always tend to get hung up on this when making my own projects. In my experience it’s usually much easier to do things properly at the beginning, than go back and fix everything you were doing wrong later. It’s also hard to change when you’ve fallen into a bad habit. But when so many people have different ideas of what the ‘right’ way is, it can be really difficult to know for sure.

For example, while doing some reading after finishing the Django Girls tutorial, I found that many people thought it was better to use class-based views. The tutorial did not have us writing class-based views. The more I read, the more I felt that was how it should be done. So I went to my code and changed about half the views to use classes. The others would have been more difficult to convert. And I realized that, although class-based views can definitely be more efficient if you’re doing something simple, they shouldn’t necessarily be used for everything. Sometimes writing your own function is better.

I hadn’t changed anything on my Django blog project for a few days because I wanted to add categories and tags, and I wasn’t sure what the best way was to implement them. I ended up following the example set by the Mozilla tutorial, which has you create a book catalog for a library, and added a Category model which was also a ManyToManyField in the Post model. This is the same way they implemented a genre for books and I figured they were fields that worked the same way – a book can have multiple genres and a blog post can have multiple categories.

I then ran into the problem of how I was going to display a list of categories on every page. I wanted to add it to my base template, but I couldn’t think of a simple way to do that. It turns out that writing a context processor was the answer. All I had to do is make a file called ‘context_processors.py’ (or maybe whatever you want, but this is the usual name) and enter this:

from .models import Category

def categories_processor(request):
    categories = Category.objects.all()
    return {'categories': categories}

This allowed me to easily add categories to my base template with a simple for loop to display the name:

<h3>Categories</h3>
    <ul>
        {% for category in categories %}
        <li> {{ category }} </li>
        {% endfor %}
    </ul>

However, I then had the issue of not knowing how I could make those categories have a count next to them to show how many posts fall into that category. I also didn’t know how I could link to a filtered post list when you clicked a category’s name. I mean, I had an idea of how it could work, but it would involve making a new view and url for each filter (there’d be a tag one soon too), and that just didn’t feel right to me. What I want is like, one view, that takes a parameter that is the filter, and then displays the posts according to that filter, using the same url and the same template. But I couldn’t seem to work out how that should be done.

I did some research, and maybe django-filter is my best option, but I’m just not really clear on how it works. I thought that maybe I should do a bit more basic Django practice since there’s still a lot that I don’t know. So far, all I’ve done are the Mozilla and Django Girls tutorials. While the Django Girls one was good, it was very basic. And the Mozilla one was more complex, but I actually did that one first, and I think a lot of it went over my head. They often told you to just ‘copy and paste this’ – though I very rarely do that when following tutorials as I learn better from typing myself – and I don’t feel they explained enough. My feeling is that when you are teaching someone something that they know nothing about, you should explain as much as possible, especially when it’s something as big as Django. I was going to use the word complex there but I’m not sure if that’s accurate, I mean I think that once you know what you’re doing you can probably use it to make websites pretty easily. But there’s a lot going on there and I wish there were more tutorials written like the Django Girls one where things are broken down in a very simple way.

So anyway, I think I’m putting my blog project on hold until I understand more about what I’m doing. I’m going to complete the official Django tutorial and then watch some Youtube tutorials that have been on my list for a while now.

I know people often say that you shouldn’t get stuck in a cycle of completing beginner tutorials over and over, but for me personally, I feel that by creating a project, even when I’m following along with a tutorial, I learn a lot. Anything that I already know is reinforced, and it also shows the different ways people do things when it comes to coding. Which brings me back to my initial point – I want to do things the right way, and the more exposure I get to different methods, the more likely I am to figure out what that is.

In addition to this I’ll continue to do coding challenges every day, which I have been for the past month or so. I also saw that apparently The Odin Project has just released a JavaScript full stack course, so I’m going to check that out. Previously I hadn’t bothered much with their course because it initially only taught Ruby on Rails, and I was focusing on Python. While I’m not a huge JavaScript fan, I know it’s useful, but what I know is fairly basic. The job I hope to apply for soon will require it so it would probably be a good idea to work on those skills.

That’s the other thing – I’m not sure I’d be using Django at all if I get this job. I just started it and liked it. I frustratingly don’t have all the details, but I was told I have to be strong in Python and have a passing knowledge of Node.js. This is pretty vague to me but it leads me to believe that they use some Node framework like perhaps Express on the backend and use Python alongside it for scripting, or something. I wish I knew more, since it would be much easier to study if I did.

Oh well, I’m going to go and hopefully learn something now.