Skip to content

DRAFT JS QUICKSTART Code Samples

Author TODO Items

Decisions affect what parts of our code execute at run-time. They are the way we are able, as developers, to choose what we want our program to do. All of this can be accomplished with the humble if statement.

The first thing to understand about the if statement is its grammar [TODO: Link]. The basic grammar looks like this.

if(conditionalExpression)
statementOrStatementBlock // true side
else
statementOrStatementBlock // false side

There are two keywords in this grammar.

  • The if keyword tells the computer we’re about to make a true/false decision based on some information (the conditionalExpression). The statementOrStatementBlock will be executed only if the conditional expression produces a true boolean result.
  • The else keyword tells the computer what to do should that conditional expression turns out to produce a false result. Note that the else portion with its statementOrStatementBlock is entirely optional.

Besides the keywords, we have these placeholder parts of the grammar.

  • The conditionalExpression is simply any expression that can produce a true or false value.
    • By the way, the words true and false are JavaScript keywords.
  • A statementOrStatementBlock is either a single statement or a single statement block (a block is zero or more statements inside curly braces - { }).
    • A single statement can be on its own line.
    • A statement block should have the opening curly brace at then end of the same line as the initial statement and the closing curly brace on its own line.

The following is an example of a statement block with properly positioned curly braces.

Sample Code
if(quantity === 0) {
// zero or more lines of code
} else {
// zero or more lines of code
}

It’s important to remember that this if-else structure provides alternate paths of logic. If one path is followed, then the other is not followed.

Let’s explore the If/Else statement with a simple example.

  1. To begin, create a file called grok-decisions.js. Then run it in the terminal with node --watch grok-decisions.js.

  2. Let’s add some code to portray using a self-serve gas station where we want to fuel up our vehicle.

    grok-decisions.js
    let bankBalance = 78.23;
    let preAuthorizationAmount = 50.00;
    if(bankBalance > preAuthorizationAmount) {
    console.log('Transaction Approved.');
    console.log('Please Remove Card Now and Lift Nozzle');
    }
  3. We’ve hard-coded values in our program, and you can probably guess what is going to be displayed on the screen. Because the bank balance is the larger of the two values, then the conditional expression bankBalance > preAuthorizationAmount results in a true, and then the code inside statement block is executed.

    If you’re using the debugger, try placing a breakpoint on the if statement and then step through the code.

  4. Let’s edit the preAuthorizationAmount and increase it to $100.

    grok-decisions.js
    let preAuthorizationAmount = 50.00;
    let preAuthorizationAmount = 100.00;
  5. Now, because $78.23 is not greater than $100.0, the code execution jumps past the instructions on the “true” side of the if statement, and nothing is displayed on the screen.

  6. Let’s add an else side to our if statement.

    grok-decisions.js
    if(bankBalance > preAuthorizationAmount) {
    console.log('Transaction Approved');
    console.log('Please Remove Card Now and Lift Nozzle');
    }
    } else {
    console.log('Transaction Declined.');
    console.log('Please Remove Your Card').;
    }
  7. Play with making changes to either the bankBalance or the preAuthorizationAmount and observe the effects. Can you control which output is generated by modifying the values of these variables?

With this simple example, a whole world of possibilities begins to open up for us as programmers. But to really grasp the possibilities, we need to add more decisions and explore more conditioal expressions.

So far, we’ve created two alternate paths of logic by adding a single if statement. Let’s see what else we can compare, and what that might mean for the total number of logical paths available to our program.

  1. Modify the grok-decisions.js to reset the preAuthorizationAmount to $50. Then add some code to track the fuel purchase and update your bank balance.

    grok-decisions.js
    let bankBalance = 78.23;
    let preAuthorizationAmount = 100.00;
    let preAuthorizationAmount = 50.00;
    let actualFuelCost;
    if(bankBalance > preAuthorizationAmount) {
    console.log('Transaction Approved.');
    console.log('Please Remove Card Now and Lift Nozzle');
    actualFuelCost = 23.98;
    } else {
    console.log('Transaction Declined.');
    console.log('Please Remove Your Card');
    actualFuelCost = 0;
    }
    console.log(`Fuel Purchase:\t$ ${actualFuelCost}`);
  2. Let’s enhance the self-serve gas station experience. Often, there’s an option to choose a car wash. Let’s weave that into our existing code.

    grok-decisions.js
    let bankBalance = 78.23;
    let preAuthorizationAmount = 50.00;
    let carWashAmount = 0;
    let actualFuelCost;
    let includeCarWash = true;
    if(includeCarWash == true) {
    carWashAmount = 19.99;
    }
    // remaining code is unchanged...

    Because we have given our carWashAmount an initial value of 0, we don’t have to have an else block on our new IF statement.

  3. Notice how the if uses includeCarWash == true as the conditional expression. Earlier, includeCarWash was given a value of true, and therefore it’s data type is boolean. Since all that a conditional expression needs is a boolean result, it’s redundant to use includeCarWash == true. Let’s fix that.

    grok-decisions.js
    if(includeCarWash == true) {
    if(includeCarWash) {
    carWashAmount = 19.99;
    }

    This is much cleaner. By the way, I was careful in choosing the name includeCarWash for our variable, because it reads smoothly for us as humans:

    “If we include the car wash…”

  4. We’ll fill out the rest of this with a receipt of all the charges. We’ll also reset the car wash amount if the pre-authorization fails.

    grok-decisions.js
    if(bankBalance > preAuthorizationAmount) {
    console.log('Transaction Approved.');
    console.log('Please Remove Card Now and Lift Nozzle');
    actualFuelCost = 23.98;
    } else {
    console.log('Transaction Declined.');
    console.log('Please Remove Your Card');
    actualFuelCost = 0;
    carWashAmount = 0;
    }
    // We'll be using these more in some later examples
    let total;
    let message;
    total = carWashAmount + actualFuelCost;
    message = `
    Fuel Purchase:\t$ ${actualFuelCost}
    Car Wash: +\t$ ${carWashAmount}
    Total: =\t$ ${total}
    `;
    console.log(`Fuel Purchase:\t$ ${actualFuelCost}`);
    console.log(message);
    bankBalance = bankBalance - total;
    console.log(`Your new balance is: $ ${bankBalance}`);
  5. ⚗️ Try some experimentation. Try editing the values for includeCarWash and preAuthorizationAmount in various combinations. Because we have two decision statements stacked on top of each other, how many alternating paths of logic are present in the code?

Let’s throw in some assorted combinations of the other relational operators with a few more if/else statements.

  1. You can think of == as being a “general equality” operator, while === is a “strict equality” operator. Strict equality requires the data types to also match.

    grok-decisions.js
    // Can we compare strings and numbers?
    const five = 5;
    const digit = '5';
    if(digit == five) {
    message = `Looks like '${digit}' and ${five} are the same.`
    console.log(message);
    } else {
    console.log('No, we treat them differently.');
    }
    if(digit === five) {
    console.log('Yup, still the same');
    } else {
    message = `Strictly speaking, '${digit}' (a ${typeof digit}) is not the same as ${five} (which is a ${typeof five})`;
    console.log(message);
    }
  2. The opposite of == is !=. Likewise, the opposite of === is !==.

    grok-decisions.js
    const seven = 7;
    if(seven != five) {
    console.log('Of course 7 is not equal to 5');
    }
    if(seven !== seven.toString()) {
    console.log('Strict equality requires the same value AND data type!');
    }
  3. We’ve seen the > operator. Our remaining operators are >=, < and <=. Have you thought about what the opposite of > is? Examine the following experiment to see if you can figure it out.

    grok-decisions.js
    if(seven >= 7) {
    console.log('\nCan you tell me which operator gives the opposite of >=?');
    }
    if(seven <= 7) {
    console.log('Can you tell me which operator gives the opposite of <=?\n');
    }
  4. There’s another little experiment that you can try. See if your ideas around “opposite” relational operators still holds.

    grok-decisions.js
    let number = 0; // Try different numbers...
    console.log(' 0')
    console.log('<---|---|---|---|---|--->');
    console.log(' The Number Line');
    if(number < 0) {
    console.log('Less than 0 |');
    }
    if(number > 0) {
    console.log(' | Greater than 0');
    }
    if(number === 0) {
    console.log(' Exactly | Zero!')
    }
    console.log(`The number is: ${number}`);

    ⚗️ Do a little more experimentation. Try different values for number and observe the results.

Relational operations are only the beginning. JavaScript also has a few Logical Operators to help us compare boolean values.

  1. We’ve seen the use of a single boolean inside a conditional expression. But what if we had two boolean values. Consider these variables.

    grok-decisions.js
    // Use these to hold true/false values
    let torpedoLoaded, targetSelected;
    // ⚗️ How many combinations of true/false can you do with two boolean variables?
    torpedoLoaded = true;
    targetSelected = true;
  2. Let’s add in some comparisons to explore the logical operators.

    grok-decisions.js
    // Logical OR operator
    if(torpedoLoaded || targetSelected) {
    // Logical NOT operator
    if(!torpedoLoaded) {
    console.log('... loading the torpedo ...');
    }
    if(!targetSelected) {
    console.log('... aquiring target ...');
    }
    }
    // Logical AND operator
    if(torpedoLoaded && targetSelected) {
    console.log('Ready to fire torpedo.');
    }
  3. ⚗️ Play with the code by trying different true/false combinations for the two variables. What do you observe?

We can combine arithmetic, relational and boolean operations to handle complex conditional expressions. When we do that, the natural order of those operations follows this precidence.

  1. Arithmetic operations are executed to produce some value.
  2. Relational operations are performed next to compare values and produce some boolean value.
  3. Logical operations are evaluated to produce a true/false result.
  1. Did you know that for most post-secondary schools in Canada, you need to be enrolled in more than three courses to be considered a full-time student?

    grok-decisions.js
    let courseCount = 4;
    let isEnrolled = false, isFullTimeStudent;
    if(courseCount > 0)
    isEnrolled = true;
    if(isEnrolled && courseCount >= 3)
    isFullTimeStudent = true;
    else
    isFullTimeStudent = false;
    console.log(`\n${courseCount} courses. Full time? ${isFullTimeStudent}`);
  2. Various financing options are available for students, but sometimes full-time students will find themselves eligible for special scholarships. Usually, there are some conditions that might apply…

    grok-decisions.js
    let netIncomeLastYear = 32_374; // $32,374
    let currentGpa = 3.8; // 😊
    let existingBursaries = 0; // 😢
    let eligibleScholarship = 0;
    // Are you eligible for extra funding?
    if(isFullTimeStudent && netIncomeLastYear / 2 < 16_198 && currentGpa >= 3.5)
    eligibleScholarship = 2_500;
    else if(isFullTimeStudent && netIncomeLastYear / 2 < 16_198 && currentGpa > 3.0)
    eligibleScholarship = 1_500;
    else if(existingBursaries < netIncomeLastYear / 8.2 && currentGpa > 3.7)
    eligibleScholarship = 2_000;
    console.log(`You are eligible for $ ${eligibleScholarship} in special funding.\n`);
  3. Review the code above carefully. Can you see the order of operations? Part of the job of a developer is to think through whatever possible logic is required to produce the correct solution.

Hopefully you’re already aware that JavaScript is a dynamically typed language. That has a bearing on decisions because you don’t need a strictly-typed true or false in a conditional expression. JavaScript supports the notion of “truthy” and “falsy” values.

  1. Remember the student funding we were exploring? We can test if any scholarships or bursaries are available. A non-zero value would be regarded as “truthy”.

    grok-decisions.js
    if(existingBursaries) {
    console.log(`You have been granted $ ${existingBursaries} in additional funding.`);
    }
    if(eligibleScholarship) {
    console.log(`You are eligible for $ ${eligibleScholarship} in additional scholarships. (Application is required)`);
    }
  2. Imagine that somewhere we have gathered information about a student. (We’ll just hard-code it for now.) We can simply check if that data exists before we proceed to process that information.

    grok-decisions.js
    let student;
    // Hard-code for this demo
    student = {
    id: 19263874,
    name: 'Stewart Dent'
    }
    // Sometime later in our code...
    if(student) { // IF we have student info...
    console.log('Your eligibility status has been forwarded to the registrar''s office');
    } else {
    console.log('Please log in to preserve your funding assessment.');
    }
  3. This could be a good opportunity to experiment with additional truthy/falsy decisions. What further examples can you create on your own?

When things go sideways...

Fixing Bugs

If you’ve made it this far, then you need to consider how we might introduce “bugs” into our code that are revealed only at run-time.

Head over to the following article to discover some of the more common logical errors that can creep into our code.

Logical Errors

Part 7 - Using Function Calls in Decisions

Section titled “Part 7 - Using Function Calls in Decisions”

If you understand what expressions are, you might have already thought of how you might involve a function call in your conditional expression.

  1. Add the following functions at the end of your script file.

    grok-decisions.js
    // Helper functions for financial assistance
    function calculateScholarship(isFullTime, currentGpa, income, bursaries) {
    let eligibleAmount = 0;
    const isLowIncome = checkIncome(income);
    const hasLowBursaries = checkBursariesAgainstIncome(bursaries, income);
    if(isFullTime && isLowIncome && hasSufficentGPA(currentGpa))
    eligibleAmount = 2_500;
    else if(isFullTime && isLowIncome && hasMinimumGPA(currentGpa))
    eligibleAmount = 1_500;
    else if(hasLowBursaries && hasHighGPA(currentGpa))
    eligibleAmount = 2_000;
    return eligibleAmount;
    }
    function checkIncome(netIncome) {
    const baseLimit = 16_198;
    // return a boolean value
    return netIncome / 2 < baseLimit;
    }
    function checkBursariesAgainstIncome(bursaries, netIncome) {
    return bursaries < netIncome / 8.2;
    }
    function hasMinimumGPA(gpa) {
    return gpa > 3.0;
    }
    function hasSufficentGPA(gpa) {
    return gpa >= 3.5;
    }
    function hasHighGPA(gpa) {
    return gpa > 3.7;
    }
  2. Return to the code where you were checking for potential scholarships and make the following edits.

    grok-decisions.js
    let netIncomeLastYear = 32_374; // $32,374
    let currentGpa = 3.8; // 😊
    let existingBursaries = 0; // 😢
    let eligibleScholarship = 0;
    let eligibleScholarship = calculateScholarship(isFullTimeStudent, currentGpa, netIncomeLastYear, existingBursaries);
    // Are you eligible for extra funding?
    if(isFullTimeStudent && netIncomeLastYear / 2 < $16_198 && currentGpa >= 3.5)
    eligibleScholarship = 2_500;
    else if(isFullTimeStudent && netIncomeLastYear / 2 < $16_198 && currentGpa > 3.0)
    eligibleScholarship = 1_500;
    else if(existingBursaries < netIncomeLastYear / 8.2 && currentGpa > 3.7)
    eligibleScholarship = 2_000;
    console.log(`You are eligible for $ ${eligibleScholarship} in special funding.\n`);
  3. Consider the effect of these changes. Does the use of functions make the decisions easier to read and understand?

Code Review

Experiment with additional changes to this tutorial. For example, what would happen if you included a 5% sales tax on the price of the car wash (calculated after price is assigned to the variable)? Are there any potential “bugs” in your code? How would you find and fix those bugs?

Perhaps you would like to add descriptions of your data types as you experiment. Consider adding these functions to your script.

Extra functions for grok-decisions.js
const describeDataType = function (value) {
let result;
if (value == undefined || value == null) {
result = `The value is ${value}`;
} else {
result = `The data type is ${value.constructor.name}`;
}
return result;
};
const getDataType = function (value) {
let result;
if (value == undefined || value == null) {
result = `${value}`; // as a string
} else {
result = value.constructor.name;
}
return result;
};
const ify = function (expression) {
let result;
let type = typeof expression;
if (type === "boolean") {
result = expression;
} else if (expression) {
result = `truthy`;
} else {
result = `falsy`;
}
return result;
};