Events

Introduction

Now that we have a handle on manipulating the DOM with JavaScript, the next step is learning how to make that happen dynamically, or on demand! Events are how you make that magic happen on your pages. Events are actions that occur on your webpage such as mouse-clicks or keypresses, and using JavaScript we can make our webpage listen and react to these events.

There are three primary ways to go about this: you can attach functions attributes directly on your HTML elements, you can set the "on_event_" property on the DOM object in your JavaScript, or you can attach event listeners to the nodes in your JavaScript. Event listeners are definitely the preferred method, but you will regularly see the others in use, so we’re going to cover all three.

Learning Objectives

  • How do "events" and "listeners" work? What are three ways to use events in your code?
  • How does "bubbling" work?

We’re going to create 3 buttons that all alert "BUTTON" when clicked. Try them all out using your own HTML file, or using something like CodePen.

Method 1 (Not recommended)

<button onclick="alert('Hello World')">Click Me</button>

This solution is less than ideal because we’re cluttering our HTML with JavaScript. Also, we can only have 1 "onclick" event per element.

Method 2 (Not recommended)

<!-- the html file -->
<button id="btn">Click Me</button>
// the JavaScript file
const btn = document.querySelector('#btn');
btn.onclick = () => alert("Hello World");

(need to review arrow functions? Arrow Functions Basics)

This is a little better. We’ve moved the JS out of the HTML and into a JS file, but we still have the problem that a DOM element can only have 1 "onclick" property.

Method 3 (Recommended)

<!-- the html file -->
<button id="btn">Click Me Too</button>
// the JavaScript file
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
  alert("Hello World");
});

Now, we maintain separation of concerns, and we also allow multiple event listeners if the need arises. Method 3 is much more flexible and powerful, though it is a bit more complex to set up.

Note that all 3 of these methods can be used with named functions like so:

<!-- the html file -->
<!-- METHOD 1 -->
<button onclick="alertFunction()">CLICK ME BABY</button>
function alertFunction() {
  alert("YAY! YOU DID IT!");
}

// METHOD 2
btn.onclick = alertFunction;

// METHOD 3
btn.addEventListener('click', alertFunction);

Using named functions can clean up your code considerably, and is a really good idea if the function is something that you are going to want to do in multiple places.

With all three methods we can access more information about the event by passing a parameter to the function that we are calling. Try this out on your own machine:

btn.addEventListener('click', function (e) {
  console.log(e);
});

Note that function (e) is a callback from addEventListener. Further explanation of callbacks can be found HERE.

The e in that function is an object that references the event itself. Within that object you have access to many useful properties and functions such as which mouse button or key was pressed, or information about the event’s target – the DOM node that was clicked.

Try this:

btn.addEventListener('click', function (e) {
  console.log(e.target);
});

and now this:

btn.addEventListener('click', function (e) {
  e.target.style.background = 'blue';
});

pretty cool eh?

Attaching listeners to groups of nodes

This might seem like a lot of code if you’re attaching lots of similar event listeners to many elements. There’s a few ways to go about doing that more efficiently. We learned above that we can get a nodelist of all of the items matching a specific selector with querySelectorAll('selector'). In order to add a listener to each of them we simply need to iterate through the whole list like so:

<div id="container">
    <button id="1">Click Me</button>
    <button id="2">Click Me</button>
    <button id="3">Click Me</button>
</div>
// buttons is a node list. It looks and acts much like an array.
const buttons = document.querySelectorAll('button');

// we use the .forEach method to iterate through each button
buttons.forEach((button) => {

  // and for each one we add a 'click' listener
  button.addEventListener('click', () => {
    alert(button.id);
  });
});

This is just the tip of the iceberg when it comes to DOM manipulation and event handling, but it’s enough to get you started with some exercises. In our examples so far we have been using the ‘click’ event exclusively, but there are many more available to you.

Some useful events include:

  • click
  • dblclick
  • keypress
  • keydown
  • keyup

You can find a more complete list with explanations of each event on this page.

Avoiding Confusion

As you’ve seen, you can define an event handler in 3 different ways.

  1. Using the addEventListener method (Recommended)
document.querySelector(".box").addEventListener( "click", function( event ){ ... });
document.querySelector("form").addEventListener( "submit", function( event ){ ... });
document.body.addEventListener( "keyup", function( event ){ ... });
  1. Using the on<EVENTNAME> property syntax (Not recommended)
document.querySelector(".box").onclick = function( event ){ ... };
document.querySelector("form").onsubmit = function( event ){ ... };
document.body.addEventListener.onkeyup = function( event ){ ... };
  1. Using an attribute with the on<EVENTNAME> directly in an HTML element (Not recommended):
<div class="box" onclick="clickHandler()">Click me</div>
<form onsubmit="submit()">
    <!-- CONTENT -->
</form>
<body onkeyup="handleKey()">

Events in the first syntax are used like this (nouns): ‘click’, ‘submit’, ‘change’, ‘scroll’, etc.

While using the 2nd syntax, are prefixed with the ‘on’ keyword: ‘onclick’, ‘onsubmit’, ‘onchange’, ‘onscroll’, etc.

The second syntax corresponds to element properties and should not be confused with the event names used in the first case.

Additional Resources

LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

Feedback

  • Is there anything we can help with up to this point? Do you have something to suggest about this chapter? Let us know in the comments below.

UPDATED: 23.02.2021

Project: Calculator

Introduction

You made it! By now you should have a really firm grasp on the fundamentals of JavaScript. Of course there’s plenty more to learn, but you should be able to create quite a bit at this point. Our final project is going to combine everything you’ve learned so far: you’re going to make an on-screen calculator using JavaScript, HTML, and CSS.

As usual with these things, there are elements of this project that are not going to be trivially easy for you, but if you’ve been following the course so far, you definitely have everything you need to finish it. We’re going to walk you through the various steps you can take, but again, how you actually implement them is up to you!

Important Note: Before you get started with this calculator project, we need to cover a word of warning. As you look into how to evaluate complex mathematical statements in JavaScript, you will likely come across the tantalizing eval() function. However, this function can be very dangerous and should not ever be used! You’ll need to build your own functions to evaluate expressions as part of this calculator project.

Assigment

Here are some use cases (abilities your project needs to have):

  1. Your calculator is going to contain functions for all of the basic math operators you typically find on simple calculators, so start by creating functions for the following items and testing them in your browser’s console.

    1. add
    2. subtract
    3. multiply
    4. divide
  2. Create a new function operate that takes an operator and 2 numbers and then calls one of the above functions on the numbers.

  3. Create a basic HTML calculator with buttons for each digit, each of the above functions and an "Equals" key.

    1. Do not worry about wiring up the JS just yet.
    2. There should also be a display for the calculator, go ahead and fill it with some dummy numbers so you can get it looking right.
    3. Add a "clear" button.
  4. Create the functions that populate the display when you click the number buttons… you should be storing the ‘display value’ in a variable somewhere for use in the next step.

  5. Make the calculator work! You’ll need to store the first number that is input into the calculator when a user presses an operator, and also save which operation has been chosen and then operate() on them when the user presses the "=" key.

    1. You should already have the code that can populate the display, so once operate() has been called, update the display with the ‘solution’ to the operation.
    2. This is the hardest part of the project. You need to figure out how to store all the values and call the operate function with them. Don’t feel bad if it takes you a while to figure out the logic.
  6. Gotchas: watch out for and fix these bugs if they show up in your code:

    1. Users should be able to string together several operations and get the right answer, with each pair of numbers being evaluated at a time. For example, 12 + 7 - 5 * 3 = should yield 42. An example of the behavior we’re looking for would be this online calculator: https://www.theonlinecalculator.com/. Note that this behavior means your calculator is not required to follow order of operations, aka PEMDAS (though there’s nothing stopping you from implementing PEMDAS if you feel like it!).
    2. You should round answers with long decimals so that they don’t overflow the screen.
    3. Pressing = before entering all of the numbers or an operator could cause problems!
    4. Pressing "clear" should wipe out any existing data.. make sure the user is really starting fresh after pressing "clear"
    5. Display a snarky error message if the user tries to divide by 0… don’t let it crash your calculator!

EXTRAS

  1. EXTRA CREDIT: Users can get floating point numbers if they do the math required to get one, but they can’t type them in yet. Add a . button and let users input decimals! Make sure you don’t let them type more than one though: 12.3.56.5. It is hard to do math on these numbers. (disable the decimal button if there’s already one in the display)

  2. EXTRA CREDIT: Make it look nice! This can be a good portfolio project… but not if it’s UGLY. At least make the operations a different color from the keypad buttons.

  3. EXTRA CREDIT: Add a "backspace" button, so the user can undo if they click the wrong number.

  4. EXTRA CREDIT: Add keyboard support!

Submission

Create a private GitHub repository, add your solution code along with your instructor(s) as collaborator(s) and submit the URL in the quiz below.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 23.10.2020

Fundamentals: Part 5

Objects

Objects are a very important part of the JavaScript language, and while for the most part you can accomplish simple and even intermediate tasks without worrying about them, any real project that you’re going to attempt is going to feature Objects. The uses of Objects in JavaScript can get deep relatively quickly, so for the moment we’re only going to cover the basics. There’ll be an in-depth dive later.

  1. This JavaScript.info article is the best place to get started with Objects.

  2. The MDN tutorial isn’t bad either, so check it out if you need another take on the subject.

Intermediate/Advanced Array Magic

Besides being a quick and handy way to store data, arrays also have a set of functions for manipulating that data in very powerful ways. Once you begin to master these functions you will start to see ways to use them all over the place! There are really only a handful of these functions… but as you’ll soon see, the possibilities of what you can do with them are near endless.

Objectives of these section:

  • Learn about the forEach Array method

  • Learn about the filter Array method

  • Learn about the map Array method

  • Learn about the sort Array method

  • Learn about the reduce Array method

  1. Start out by watching the video JavaScript Array Cardio Practice – Day 1 from Wes Bos.

Duration: 24 minutes

To follow along clone the JavaScript30 repository.

  1. Watch and code with Part 2 of Wes Bos’s array series.

Duration: 8 minutes

Practice

You have been through a ton of content, and it would not be surprising if you were feeling rather overwhelmed at this point. Let’s take a little time to slow down and practice this stuff with more coding exercises. I’ll warn you now: some of these get pretty difficult, but if you’ve done the lessons you should have covered everything you need to know to solve them. Don’t be afraid to go back and review if you find that you can’t remember something, that’s part of the process. If you get stuck reach out for help in the usual channels.

Exercise

Go to the Exercises Repository and follow the instructions on how to complete and submit the exercise.

Want MORE practice?

You really can’t spend too much time reviewing and practicing the fundamentals that we’ve covered here and luckily for you there are several websites that offer just this type of thing. Seriously, the better you grasp and the more fluently you can use the fundamental building blocks of JavaScript, the easier the hard stuff is going to come to you when we get to it. Take a minute to check out the following links.

  • Exercism – Uses a neat command-line interface to download and submit exercises and allows you to give and get feedback on your solutions.

  • CodeWars – A neat gamified system with leveled exercises. As you complete more exercises you level up and access more difficult ones.

  • HackerRank – Similar in setup to CodeWars, but this site is more focused on interview question type tasks. Some companies even use this site to interview candidates.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 12.11.2020

Project: Etch-a-Sketch

Introduction

In this project you’ll be creating a pretty neat toy for your portfolio to flex your DOM manipulation skills. You’re going to build a browser version of something between a sketchpad and an Etch-A-Sketch.

This project should not be easy for you. You’ll probably have to Google frequently to get the right JavaScript methods and CSS to use – in fact, that’s the point! You can build this using the tools that you have already learned and there are plenty of resources on the net for learning stuff that we haven’t covered yet if you decide you need it. We’ll walk you through the basic steps, but it will be up to you to actually implement them.

Instructions

Follow the instructions here in order to complete and submit the exercise.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 24.11.2020

DOM Manipulation

Introduction

One of the most unique and useful abilities of JavaScript is its ability to manipulate the web pages. It can manipulate both the HTML and CSS of any web page through the DOM. But what is the DOM, and how do we go about changing it? Let’s jump right in…

Learning Objectives

  • What is DOM in relation to a webpage?
  • What’s the difference between a "node" and an "element"?
  • How do you target nodes with "selectors"?
  • What are the basic methods for finding/adding/removing and altering DOM nodes?
  • What is the difference between a "nodelist" and an "array of nodes"?

Study

Watch An Introduction to Browser Rendering.

Duration: 8 minutes

Read: What, exactly, is the DOM?

DOM – Document Object Model

The DOM (or Document Object Model) is a tree-like representation of the contents of a webpage – a tree of "nodes" with different relationships depending on how they’re arranged in the HTML document.

<div id="container">
  <div class="display"></div>
  <div class="controls"></div>
</div>

In the above example, the <div class="display"></div> is a "child" of <div id="container"></div> and a sibling to <div class="controls"></div>. Think of it like a family tree. <div id="container"></div> is a parent, with its children on the next level, each on their own "branch".

Targeting Nodes with Selectors

When working with the DOM, you use "selectors" to target the nodes you want to work with. You can use a combination of CSS-style selectors and relationship properties to target the nodes you want. Let’s start with CSS-style selectors. In the above example, you could use the following selectors to refer to <div class="display"></div>:

  • div.display
  • .display
  • #container > .display
  • div#container > div.display

You can also use relational selectors (i.e. firstElementChild or lastElementChild etc.) with special properties owned by the nodes.

const container = document.querySelector('#container');
// select the #container div (don't worry about the syntax, we'll get there)

console.dir(container.firstElementChild);                      
// select the first child of #container => .display

const controls = document.querySelector('.controls');   
// select the .controls div

console.dir(controls.previousElementSibling);                  
// selects the prior sibling => .display

So you’re identifying a certain node based on its relationships to the nodes around it.

DOM methods

When your HTML code is parsed by a web browser, it is converted to the DOM as was mentioned above. One of the primary differences is that these nodes are objects that have many properties and methods attached to them. These properties and methods are the primary tools we are going to use to manipulate our webpage with JavaScript. We’ll start with the query selectors – those that help you target nodes.

Query Selectors

  • element.querySelector(selector) returns reference to the first match of selector
  • element.querySelectorAll(selectors) returns a "nodelist" containing references to all of the matches of the selectors

*There are several other, more specific queries, that offer potential (marginal) performance benefits, but we won’t be going over them now.

It’s important to note that when using querySelectorAll, the return value is not an array. It looks like an array, and it somewhat acts like an array, but it’s really a "nodelist". The big distinction is that several array methods are missing from nodelists. One solution, if problems arise, is to convert the nodelist into an array. You can do this with Array.from() or the spread operator.

Element Creation

  • document.createElement(tagName[, options]) creates a new element of tag type tagName. [options] in this case means you can add some optional parameters to the function. Don’t worry about these at this point.
const div = document.createElement('div');

This function does NOT put your new element into the DOM – it simply creates it in memory. This is so that you can manipulate the element (by adding styles, classes, ids, text etc.) before placing it on the page. You can place the element into the DOM with one of the following methods.

Append Elements

  • parentNode.appendChild(childNode) appends childNode as the last child of parentNode
  • parentNode.insertBefore(newNode, referenceNode) inserts newNode into parentNode before referenceNode

Remove Elements

  • parentNode.removeChild(child) removes child from parentNode on the DOM and returns reference to child

Altering Elements

When you have a reference to an element, you can use that reference to alter the element’s own properties. This allows you to do many useful alterations, like adding/removing and altering attributes, changing classes, adding inline style information and more.

const div = document.createElement('div');                     
// create a new div referenced in the variable 'div'

Adding inline style

div.style.color = 'blue';                                      
// adds the indicated style rule

div.style.cssText = 'color: blue; background: white';          
// adds several style rules

div.setAttribute('style', 'color: blue; background: white');    
// adds several style rules

See DOM Enlightenment’s section on CSS Style rules for more info on inline styles.

Note that if you’re accessing a kebab-cased css rule from JS, you’ll either need to use camelcase or you’ll need to use bracket notation instead of dot notation.

div.style.background-color // doesn't work - attempts to subtract color from div.style.background
div.style.backgroundColor // accesses the divs background-color style
div.style['background-color'] // also works
div.style.cssText = "background-color: white" // ok in a string

Editing Attributes

div.setAttribute('id', 'theDiv');                              
// if id exists update it to 'theDiv' else create an id
// with value "theDiv"

div.getAttribute('id');                                        
// returns value of specified attribute, in this case
// "theDiv"

div.removeAttribute('id');                                     
// removes specified attribute

See MDNs section on HTML Attributes for more info on available attributes.

Working with classes

div.classList.add('new');                                      
// adds class "new" to your new div

div.classList.remove('new');                                   
// remove "new" class from div

div.classList.toggle('active');                                
// if div doesn't have class "active" then add it, or if
// it does, then remove it

It is often standard (and more clean) to toggle a CSS style rather than adding and removing inline CSS.

Adding text content

div.textContent = 'Hello World!'                               
// creates a text node containing "Hello World!" and
// inserts it in div

Adding HTML content

div.innerHTML = '<span>Hello World!</span>';                   
// renders the html inside div

*Note that textContent is preferable for adding text, and innerHTML should be used sparingly as it can create security risks if misused.

Let’s take a minute to review what we’ve covered and give you a chance to practice this stuff before moving on. Check out this example of creating and appending a DOM element to a webpage.

<!-- your html file: -->
<body>
  <h1>
    THE TITLE OF YOUR WEBPAGE
  </h1>
  <div id="container"></div>
</body>
// your javascript file
const container = document.querySelector('#container');

const content = document.createElement('div');
content.classList.add('content');
content.textContent = 'This is the glorious text-content!';

container.appendChild(content);

In the JavaScript file, first we get a reference to the container div that already exists in our HTML. Then we create a new div and store it in the variable content. We add a class and some text to the content div and finally append that div to container. All in all it’s a simple process. After the JavaScript code is run, our DOM tree will look like this:

<!-- The DOM -->
<body>
  <h1>
    THE TITLE OF YOUR WEBPAGE
  </h1>
  <div id="container">
  	<div class="content">
      This is the glorious text-content!
    </div>
  </div>
</body>

Keep in mind that the JavaScript does not alter your HTML, but the DOM – your HTML file will look the same, but the JavaScript changes what the browser renders.

Important note: Your JavaScript, for the most part, is run whenever the JS file is run, or when the script tag is encountered in the HTML. If you are including your JavaScript at the top of your file, many of these DOM manipulation methods will not work because the JS code is being run before the nodes are created in the DOM. The simplest way to fix this is to include your JavaScript at the bottom of your HTML file so that it gets run after the DOM nodes are parsed and created.

Additional Resources


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 23.02.2021

CONTRIBUTORS:

Fundamentals: Part 4

Arrays

Strings and numbers may be our building blocks but as your scripts get more complex you’re going to need a way to deal with large quantities of them. Luckily, JavaScript has a couple of data types that are used for just that. An Array is simply an ordered collection of values (Strings, Numbers, other Arrays, etc.).

Watch this short introductory video on Arrays by Code.org:

Duration: 4 minutes

Watch this recorded Live Session (04/11/2020) about String and Array Methods

Part 1/3 | Duration: 1 hour

Part 2/3 | Duration: 2 hours

Part 3/3 | Duration: 1 hour

The code and exercises for this live session can be found here: JavaScript: Array and String Methods.

Do you have any questions regarding the concepts and code presented in the videos? Leave your questions and comments on the comments section at the bottom of the page.

  1. Carefully go through the JavaScript Arrays tutorial at W3Schools and make sure to practice the concepts on your own coding environment. Try as many examples as possible for every concept mentioned in the tutorial and don’t forget to complete the quizzes at the end fo the page. (Estimated reading and practicing time: 8~10h)

Some things to be aware of while going through the tutorial:

Avoid using var to declare variables in JavaScript. Prefer the modern and safer let keyword. You will learn more about the distinction at later chapters and live sessions.

Avoid using vague and meaningless variable names such as x or y as mentioned in the tutorial. Always prefer meaningful and descriptive names. See examples below:

BAD

var x = cars.length;   
var y = cars.sort();   

MUCH BETTER

let carsLength = cars.length;   
let sortedCars = cars.sort();   
  1. Read the JavaScript Array Methods post at W3Schools which covers some of the most useful built-in array methods. These fundamentals are something you’ll use every day, so don’t rush too much and miss out! Practice as much as you can on each concept, create your own examples, try to think of real-life applications for each method and don’t forget to complete the quiz at the end of the page.

The same best practices mentioned above (avoid var, use meaningful variable names) apply to this tutorial also.

You can play around with this codepen we created to get a better understanding of how the Array splice method works.

NOTES: If you are unaware of the following command mentioned in this tutorial, here’s a short explanation of what it does:

document.getElementById("demo").innerHTML = fruits;

This command searches through the document (our HTML page), for an element with id demo and replaces its HTML content with the contents of the fruits variable.

For example, let’s say we have the following HTML content in our document:

<div id="target">Some content here</div>

The following code will replace the current HTML content of this div (Some content here) with <strong>JS rocks!</strong>:

let content = "<strong>JS rocks!</strong>";
document.getElementById("target").innerHTML = content;

The getElementById command is part of the so-called DOM Manipulation API, a fancy word for the set of JavaScript commands available to us for manipulating our page’s HTML and CSS (adding elements, removing elements, creating elements, updating the elements’ content, and much much more). This is the true power of JS.

Loops

Computers don’t get tired, and they’re really really fast! For that reason they are well suited to solving problems that involve doing calculations multiple times. In some cases a computer will be able to repeat a task thousands or even millions of times in just a few short seconds where it might take a human many hours. (obviously speed here depends on the complexity of the calculation and the speed of the computer itself). One way to make a computer do a repetitive task is using a loop

  1. Read this MDN article: Looping Code. It’s a long one, but make sure you tackle the ‘Active Learning’ sections at the bottom of the page.

  2. Once again, same info, slightly different context from JavaScript.info (Skim the info if you think you know it all, but don’t forget the tasks at the end of the page. You learn best by doing)

Test Driven Development

Test Driven Development (TDD) is a phrase you often hear in the dev world. It refers to the practice of writing automated tests that describe how your code should work before you actually write the code. For example, if you want to write a function that adds a couple of numbers, you would first write a test that uses the function and supplies the expected output. Before you write your code the test will fail, and you should be able to know that your code works correctly when the tests pass.

In many ways TDD is much more productive than writing code without tests. If we didn’t have the test for the adding function above, we would have to run the code ourselves over and over, plugging in different numbers until we were sure that it was working… not a big deal for a simple add(2, 2), but imagine having to do that for more complicated functions, like checking whether or not someone has won a game of tic tac toe: (game_win(["o", null,"x",null,"x",null,"x", "o", "o"])) If you didn’t do TDD then you might actually have to play multiple games against yourself just to test if the function was working correctly!

We will teach you the art of actually writing these tests later in the course. The following exercises have the tests already written out for you. All you have to do is read the specs and write the code that makes them pass! The very first exercise (01-helloWorld) is intentionally very simple and walks you through the process of running the tests and making them pass.

Exercises

Complete the following exercises found in the repository here and submit the Quiz.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 27.11.2020

  • [27.11.2020] Added codepen to better understand Array.prototype.splice

Clean Code

Writing Clean Code

Developers spend SO MUCH more time reading code than writing it. This is true even with your own code. As a favor to yourself and whoever will need to use, maintain, or further develop your code, please learn to write readable code.

Consider the following 2 snippets of JavaScript:
ugly, hard to read code:

const x =
function(z) {
let w = 0;z.forEach(
function(q){
     w += q;
});return w;
};

x([2, 2, 2]);

clean and easy to read code:

const sumArray = function(array) {
  let sum = 0;
  array.forEach(function(number) {
    sum += number;
  });
  return sum;
};

sumArray([2, 2, 2]);

Believe it or not, both of those functions do the exact same thing (in the exact same way!), and both of them are perfectly valid code, but obviously the second one is much easier to follow. Imagine you’re working on a project with someone else and they’ve written the first function… how long is it going to take you to figure out what’s going on there so you can do your work? Imagine you’re working on a project all by yourself and YOU wrote the first function a week or two ago… chances are good that you aren’t going to remember exactly what you were up to there and it’s still going to take you a good while to figure it all out again.

The second one, however, is much easier to follow. Even if you don’t know exactly what everything in the code is doing, things are named clearly enough that you could guess, and the indentation is consistent enough that it’s easy to parse the different parts of the function.

There are many different opinions on what constitutes great JavaScript code. The most important thing is just that you’re consistent. The war between coders that use tabs and coders that use spaces to indent their code is so engrained that it’s essentially a joke by now, but it doesn’t really matter as long as you’re consistent.

Rules of Thumb

  1. Indentation: It doesn’t really matter what style of indentation you use. Various JS style-guides recommend different options, and one is not really superior to the other. What is important, however, is consistency. In our examples we will use 2 spaces for indentation.

  2. Semicolons: Semicolons are mostly optional in JavaScript because the JS compiler will automatically insert them if they are omitted. This functionality CAN break in certain situations leading to bugs in your code so…

It is better to get used to adding semi-colons;

  1. Line length: Again, different style guides will recommend different options for this one, but just about ALL of them suggest limiting the length of each line of code. This rule is not quite as strict as some of the others, but as a general rule, your code will be easier to read if you manually break lines that are longer than about 80 characters. Many code editors have a line in the display to show when you have crossed this threshold. When manually breaking lines, you should indent the second line 2 levels, and should try to break immediately after an operator or comma:
   let reallyReallyLongLine = something + somethingElse + anotherThing +
   		howManyTacos + oneMoreReallyLongThing;
  1. Naming Things: Names for functions and variables should be descriptive. Always use camelCase. To keep things consistent and easy to read, variables should always begin with a noun and functions with a verb. It is ok to use single characters as variable names in the context of a loop or a callback function, but not elsewhere.
   // Good
   const numberOfThings = 10
   const myName = "Thor"
   const selected = true

   // Bad (these start with verbs, could be confused for functions)
   const getCount = 10
   const isSelected = true

   // Good
   function getCount() {
     return numberOfThings
   }

   // Bad (it's a noun)
   function myName() {
     return "Thor"
   }

Study

Read through these articles that discuss a few elements of writing good clean code.

  1. This list of clean-code tips.

  2. This article, and this one too about the role of comments in your code.

  3. Study the following examples (all of them are real examples from student code) and make use to keep these rules in mind when naming variables yourselves:

Proper Naming for Functions and Variables

  • Name your variables and functions according to what they do.
  • Use verbs for functions and nouns for variables
  • Try to use descriptive names.
Example 1

BAD

myFunction(){ ... }
myFunction2(){ ... }

BETTER

function openMenu(){ ... }
function closeWindow(){ ... }
Example 2

BAD

This next function displays a range input field.

function rangeOutput(){ ... }

BETTER

It should probably be named using a verb that describes what it does.

function outputRange(){ ... }
Example 3

BAD

Can you guess what does the next function do? The name is too vague and ambiguous.

propTypeFunction();
Example 4

BAD

let sortArray = [ 1, 3, 2 ];
sortArray.sort();

BETTER

Prefer nouns when naming variables.

let sortedArray = [ 1, 3, 2 ];
sortedArray.sort();
Example 5

BAD

What does the tempArray hold? Try to be more descriptive.

let tempArray = entries.filter( getOdd );

BETTER

let oddEntriesArray = entries.filter( getOdd );
Example 6

BAD

What kind of object does the variable hold?

let object = new Category( categoryId, $categoryName );
// OR:
let object = new Article( articleId,  text);

BETTER

let category = new Category( categoryId, categoryName );
let article = new Article( articleId, text );

Additional Resources


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

Project: Rock Paper Scissors

Introduction

We’re going to make a simple implementation of grade-school classic "rock paper scissors". If you don’t know what that is check the wikipedia article or this ridiculous step-by-step. For the moment we’re just going to play the game from the browser console, but we will revisit it and add a front end later so don’t forget to keep the code on GitHub!

Assignment

Check the instructions here.

Once you’ve completed and tested your code submit the GitHub URL to the form below.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 24.11.2020

Fundamentals: Part 3

Functions

Things are about to get really exciting. So far you have been writing an impressive amount of code to solve various problems, but that code has not been as useful as it could be. Imagine taking one of your scripts and bundling it into a little package that you could use over and over again without having to rewrite or change the code. That’s the power of functions, and they’re used constantly in programming languages, and of course, in JavaScript.

Study

We’ll begin by this short introduction to JavaScript function by Mosh Hamedani and then move on to the reading material that goes in-depth. Try to pause the video, and code along with Mosh, as he describes these basic function concepts.

Watch this recording of our live session with Paulin de Naupois which introduces JavaScript functions.

Duration: 100 minutes

Do you have any questions regarding the concepts and code presented in the videos? Leave your questions and comments on the comments section at the bottom of the page.


Now, we’ll get more serious with a couple of intensive articles.

  1. Start by reading this article Function Basics from Javascript.info. We’ve mentioned this before, but JavaScript has changed a bit over the years and functions have recently received some innovation. This article covers one of the more useful new abilities: ‘default parameters’. (NOTE: The last "task" at the end of this lesson uses loops, which you will learn about in the next lesson. Don’t worry about that one.)

  2. Finally, read about Function Expressions in JavaScript to give you a little more context, and read this article about Arrow Functions for an introduction to a relatively new feature in modern JavaScript called the arrow function.

Arrow functions are useful but not crucial, so don’t worry about them too much just yet. We include them here because you are likely to encounter them as you move forward, and it’s better that you have at least some idea of what you’re looking at whenever they crop up.

  1. Read this article about return values.

  2. Let’s discuss parameters and arguments in the context of the following example function:

function favoriteAnimal(animal) {
   console.log(animal + " is my favorite animal!")
}

favoriteAnimal('Goat')

In JavaScript, parameters are the items listed between the parentheses in the function declaration. Function arguments are the actual values we decide to pass to the function. In the example above, the function definition is written on the first line: function favoriteAnimal(animal). The parameter, animal, is found inside the parentheses. We could just as easily replace animal with pet, x, or blah. But in this case, naming the parameter animal gives someone reading our code a bit of context so that they don’t have to guess what animal may eventually contain.

By putting animal inside the parentheses of the favoriteAnimal() function, we are telling JavaScript that we will send some value to our favoriteAnimal function. This means that animal is just a placeholder for some future value. But what value are we sending?

The last line, favoriteAnimal('Goat'), is where we are calling our favoriteAnimal function and passing the value Goat inside that function. Here, Goat is our argument. We are telling the favoriteAnimal function, "Please send ‘Goat’ to the favoriteAnimal function and use ‘Goat’ wherever the ‘animal’ placeholder is."

Because of the flexibility that using a parameter provides, we can declare any animal to be our favorite. Feel free to experiment with the code on your own and replace Goat with your favorite animal. Notice how we can change the argument to anything we like? Try changing animal in the function declaration and in the function body, too. What happens when you do?

  1. Take this interactive tutorial and learn more about the difference between declaring variables with the var keyword and using the let keyword (Preferred way). For now, you can omit the last section (Declaring with const) as it describes concepts that you are not yet familiar with. If you feel adventurous, you try it!

Function vs Block Scopes

Don’t forget to practice before leaving this interactive tutorial.

  1. Finally, take a look at this lengthy MDN article. Pay special attention to the sections on ‘Function Scope’. Scope is a topic that commonly trips up both beginner and intermediate coders, so it pays to spend some time with it up front. See if there are sections in the article that supplement the previous resources.

Code Smell (Alert)

The wikipedia article on Code Smells, describes them as follows: In computer programming, a code smell is any characteristic in the source code of a program that possibly indicates a deeper problem.

At this point, and since we are introduced to functions, you need to watch the following video and keep the suggestions and rules mentioned in it in your course notebook (try using pen and paper on some of the notes. They will greatly improve your learning efficiency. Keeping a digital version of the notes, also comes in handy.). From now on, and whenever you are creating functions, keep these best practices in mind and try to avoid code smells.

Smelly code and long functions Duration: 3 minutes

After watching the video, continue by reading the following article by Martin Fowler*

*You definitely want to bookmark Martin Fowler’s site and follow him online.

The arguments object

Watch this video from an SHA Live Session (25.11.2020) which explains the arguments object which is accessible inside functions declared with the function keyword.

What you’ll learn:

  • What is the arguments object?
  • What is its type?
  • Can it be used as an argument?
  • What are its use cases?
  • Is it helpful if it is converted into an Array?
  • What type of data types does the arguments object accept? (In short: any value)

Duration: 25 minutes

How do you convert the arguments object into an Array?

function a(){

	const arrArg = Array.from(arguments);
	console.log( arrArg.reverse() );

}

a(1,2,3);

References:

Assignment

Follow the instructions found in the Exercises Repository and sumbit your assignment.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)

UPDATED: 27.11.2020

  • Adding video about the arguments object

Developer Tools: Part 2

Introduction

Knowing how to use the Developers Tools inside your browser is an important skill for any web developer. The Developer Tools are useful for running JavaScript code, editing HTML and CSS styles without having to refresh the page, or viewing performance data. They also save you lots of time. Getting started couldn’t be any easier. You should already be familiar with using them for debugging and working on HTML and CSS, so let’s take a look at how they can benefit us when writing JavaScript.

Opening Dev Tools

There are three ways to open the Developer Tools menu:

  1. From the Browser Menu:
    • Chrome: Select the Chrome Menu > More Tools > Developer Tools
    • Firefox: Select the Firefox Menu > Web Developer> Toggle Tools
  2. Right click anywhere on a webpage and select Inspect
  3. Use the keyboard shortcut F12 or CTRL + Shift + I (option + command + I on Mac)

Hands-on

1.Watch this introductory video by The Net Ninja on using the JavaScript Console.

Duration: 5 minutes

Developer Tools in Google Chrome / Duration: 5 minutes
  1. Watch the first 33 minutes of this in-depth video by Traversy Media and learn all about the powerful tools available through in Chrome’s Developer Tools

Duration: 34 minute (The video is set to stop at 33:35)

  1. Head to the Chrome DevTools Documentation by Google. The following subsections cover what you’ll be using the Developer Tools for 95% of the time. Feel free to skip the elements you are already familiar with:

    • Open DevTools
    • CSS
      1. Get Started with Viewing and Changing CSS
      2. CSS Reference
    • Console
      1. Overview
    • Mobile Simulation
      1. Overview
    • DOM
      1. Get Started
    • JavaScript
      1. Get Started
      2. Pause Your Code With Breakpoints
  2. After becoming familiar with the Chrome DevTools, install and open up Mozilla FireFox check and compare the Developer tools. You must familiarize yourself with at least 3 browsers and their Developer tools in order to be able to debug browser-specific issues.

Additional Resources

  1. Learn 14 tips and tricks in this JavaScript 30 Video by Wes Bos.

Duration: 10 minutes

14 Must Know Chrome Dev Tools Tricks / Duration: 10 minutes

Assignment

  • Use Loom or another screen recording software to record a small video (5 minutes max) in which you’ll demonstrate and describe the following DevTools capabilities:
    • Open up the DevTools
    • Switch to Mobile/Tablet View
    • Check/Uncheck (toggle) some CSS properties
    • Change the (text) content of some Element
    • Add/remove CSS classes from an element
    • Delete an element
    • Copy/Paste an element somewhere in the HTML
    • Force the :hover state on an element
    • Use the color picker to change either the color or background-color of an element
    • Modify some CSS rule’s pixel values using the keys
    • Find the width, margin, border and padding of an element’s Box model using the Computed panel
    • Get a reference to an HTML element in JavaScript ($0)
    • Run some console assertions

Record your video, add the URL in a text file named devtools-part2-screencast.txt and upload it in the Assignment panel below. In case you use some other kind of recording software, upload the file in Google Drive or DropBox, share the video link and add the relevant URL in the text file.


Material based on Erik Trautman | The Odin Project
LOOKING FOR HELP?

When looking for help, try doing so in the following order:

  • Did you try everything you could?
  • Did you read the documentation?
  • Did you Google for it?
  • Did you post your question on Slack/Forum?
  • Did you ask your fellow students for help?
  • Did you ask your Mentors for help?
  • Did you leave a comment on the comments section of this page?
  • Did you ask your Instructor for help?
    • Did you arrange and appointment with your instructor using Calendly? Visit this URL and set up an appointment: https://calendly.com/kostasx
    • Is it urgent? Did you try reaching him on Slack? Search for: Kostas Minaidis (kostasx)