Lesson Weekend

Over the course of this section, we will build an application from Introduction to Programming based on Triangle Tracker. There's a good chance you have a repo with your own triangle project, but even if you don't (or it's not working), don't worry. We will walk through the project step by step. This section is not about learning JavaScript itself. Instead, we are focused on using JavaScript libraries and external tools to build our projects.

We'll start with building a full-fledged environment for our application. We aren't going to focus on the business logic just yet. For now, the method that checks to see if three lengths make a triangle will just return "I can't answer that question yet!"

Also, we recommend that you don't make any commits or push your code just yet. We will be learning some additional Git best practices later in this section in the following lesson: Git Best Practices and Adding a .gitignore File.

Once we've finished building our environment, we'll be ready to learn about how to use TDD with Jest. At that point, we'll build out our business logic.

First, we'll need some starter code. We'll start with the same structure we've used in the past:

shape-tracker/
├── index.html
├── src
│   ├── main.js
│   └── triangle.js
└── css
    └── styles.css

We have an index.html file, a CSS stylesheet, and two JavaScript logic files, one for the user interface and one for the business logic. A few things to note: we are calling this shape-tracker, not triangle-tracker, because we will eventually expand our application to include other shapes. We're also using a few new naming conventions. Our user logic will go in a file called main.js. This is a common convention for entry point files with webpack. But that's getting ahead of ourselves - we don't need to know about webpack yet! Just know that we are using the naming convention now to help make the transition to webpack go smoothly. Finally, we call the directory holding our JavaScript files src instead of js. Both are fine but src is a common naming convention in the industry. Our project will also be using jQuery but we will just link to a CDN in our main.js file for now.

Here's the code so far. First the HTML:

index.html
<!DOCTYPE html>
<html lang="en-US">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script type="text/javascript" src="src/main.js"></script>
  <script type="text/javascript" src="src/triangle.js"></script>
  <link rel="stylesheet" href="css/styles.css">
  <title>Shape Tracker</title>
</head>
<body>
  <h3>Enter three lengths to determine if they can make a triangle.</h3>
  <form id="triangle-checker-form">
    <label for="length1">Enter a number:</label>
    <input id="length1" type="number">
    <label for="length2">Enter a number:</label>
    <input id="length2" type="number">
    <label for="length3">Enter a number:</label>
    <input id="length3" type="number">
    <button type="submit">Submit</button>
  </form>
  <ul id="response"></ul>
</body>
</html>

There's not much to see here - a form for getting three length values and an id that will display the response from the application. One thing worth noting - you can see how we already have three script tags for JavaScript - plus we are linking to a CSS file as well. What if our application was also handling ten other shapes and they each had their own file? Well, that would be ten more script tags. And what if we had multiple stylesheets? Even more links to files. We barely have any code so far so it's easy to see how things can get cluttered very quickly. But that's one of many reasons we are switching to a full-fledged environment for our code.

Next, our src code. Here's the business logic:

src/triangle.js
function Triangle(side1, side2, side3) {
  this.side1 = side1;
  this.side2 = side2;
  this.side3 = side3;
}

Triangle.prototype.checkType = function() {
  return "I can't answer that yet!";
}

We add just enough code to be able to create a Triangle object and call the Triangle.prototype.checkType() method. As we mentioned before, this method just returns "I can't answer that yet!" for now. We won't be updating this method until we start exploring test-driven development with Jest.

Here's our user interface logic:

src/main.js
$(document).ready(function() {
  $('#triangle-checker-form').submit(function(event) {
    event.preventDefault();
    const length1 = $('#length1').val();
    const length2 = $('#length2').val();
    const length3 = $('#length3').val();
    const triangle = new Triangle(length1, length2, length3)
    const response = triangle.checkType();
    $('#response').append("<p>" + response + "</p>");
  });
});

Finally, here's our CSS file. There's just enough code to say, "hey, this works and I'm actually doing something!"

css/styles.css
body {
  background-color: lightblue;
}

Ahh, light blue. Very relaxing. Don't forget to take care of yourself and take a deep breath during those moments when the problem solving gets tough and frustrating.

We can open this in the browser and see what we have:

Our very rudimentary shape tracker application.

Well, that's really not much. But we needed four files and nearly fifty lines of code to do next to nothing. Would this way of doing things work with an application like Flickr? No way. Imagine our little application eventually becoming a full-fledged app that teaches kids about different kinds of shapes - an app that could easily run to thousands of lines of code. And let's take it a step further. What if it were part of a math application for K through 12, ranging from simple addition and shapes to algebra and calculus? Make that application interactive, add log ins for students, allow teachers to track student progress and administrators to track teacher progress and... well, you get the picture. That application would be huge. It simply wouldn't work to use the code structure we've used so far.

There's another problem here, one that we haven't really discussed because it hasn't been an issue with smaller applications. Everything works correctly in our application so far, but how are the user interface and business logic files communicating with each other? Everything just works, but how?

Well, when our HTML file loads, it also loads all the resources in our script tags. Our HTML is translated to the DOM and all of our JavaScript methods are added to the window object. window just represents the open browser window we're in, and it handles a lot of code. We can see this for ourselves by opening our application and typing window in the console, then expanding it to see everything inside it. Yep, our Triangle prototype is right there. We don't even have to use debugger; to get inside the scope of our business logic. That's because window is global - along with our Triangle prototype. It's not causing problems in our tiny little app. However, as we now know, at least in theory, globally-scoped variables can cause huge problems in larger applications.

In the next lesson, we'll start the process of transitioning our application to one with a fully-functioning environment - the kind of environment we'll commonly see at tech companies.

Lesson 3 of 48
Last updated April 6, 2021