// controller function
const getValues = () => {
let startValue = parseInt(document.getElementById("startValue").value);
let endValue = parseInt(document.getElementById("endValue").value);
let counter = parseInt(document.getElementById("counter").value);
// error message if NaN
if (isNaN(startValue) || isNaN(endValue) || isNaN(counter)) {
Swal.fire({
icon: "error",
title: "Oops!",
text: "Enter valid numbers only.",
backdrop: false,
});
} else {
const outputStr = generateFizzBuzz(startValue, endValue, counter);
displayFizzBuzz(outputStr);
}
};
// business/logic function
const generateFizzBuzz = (fizz, buzz, maximum = 100, counter = 1, results = "") => {
// check fizzbuzz conditions, add corresponding string to results
if (counter % fizz === 0 && counter % buzz === 0) {
results += `FizzBuzz `;
} else if (counter % fizz === 0) {
results += `Fizz `;
} else if (counter % buzz === 0) {
results += `Buzz `;
} else {
results += `${counter} `;
}
// if counter is equal to maximum, return results
if (counter === maximum) {
return results;
} else {
// increment and recurse
counter++;
return generateFizzBuzz(fizz, buzz, maximum, counter, results);
}
};
// view function
const displayFizzBuzz = (str) => {
let tableBody = document.getElementById("results");
tableBody.innerHTML = str;
};
There are three key functions that make this program run properly:
getValues
This function searches our HTML by ID for corresponding values that the user enters.
generateFizzBuzz
This is the meat and bones of our app. All of the logic determining
how to count to the maximum number and how to replace certain
numbers with different words lies here.
I have done this challenge several times previously, so in order to
make it a bit trickier, traditional loops are not used here.
Instead, a strategy of "recursion" is used to count.
normally a function has some logic and a return statement for an
output i.e. "return a + b;" But a recursive function returns itself.
It calls it's own function name to run again and again and again.
In order to stop it from running until the application crashes, it's
necessary to have a counter as well as a stopping condition. for
example, if you had a counter set to 1, say your function increases
the counter by one each time it runs, and you declare in your
function "if the counter is ever equal to the number 3, stop
recursing and do something else." you'll successfully escape the
infinite loop after three times.
displayString
This function is simply here to show off the output onto the website for the user. It looks for an empty table to send the output table cells, and pastes the results as a number or string of text one by one.
Together, these functions keep each piece of complexity separate, so that it is easy to read, understand, and manipulate. I found this to be a fun challenge, and it's part of why JavaScript has a special place in my heart as a quirky yet sophisticated language.