Checking Steps
📝 We continue in the Speedy Chef project folder throughout this section.
What we will be doing
The wastedPizzas function we just created will be useful again. We are now going to check the steps taken by the chef, and make sure they are correct before adding to the oven. For example, we want to ensure the dough is rolled before adding the sauce.
Currently, we can add as many pizzas as we want to the oven, and we also do not check the ingredients are correct.
The stepsCompleted function
To check these ingredients, create a new function at the bottom of the script file:
// need to take in pizza name so we can get the steps
function stepsCompleted(pizzaName) {}
This function will return either true or false depending if the steps taken are correct.
This true or false value will then determine if we can add the pizza to the oven. In the addToOven function, we can call this stepsCompleted function, and store the returned Boolean into a variable:
function addToOven() {
  pizzasCompleteForOrder++;
  const pizzaName = document.querySelector('#current_pizza').innerText;
  if (pizzaName) {
    // Call `stepsCompleted` function inside the if statement:
    const canAddToOven = stepsCompleted(pizzaName);
    // ...
  }
}
We add this inside the if statement to first check if a pizza has been clicked on in the "Working on" section. This selects the pizza we are going to make in the kitchen.
Checking if we can push a pizza to the oven
The canAddToOven variable now determines if a pizza can be placed into the oven. Add an if statement to only run the code if canAddToOven is true:
function addToOven() {
    pizzasCompleteForOrder++;
    const pizzaName = document.querySelector("#current_pizza").innerText;
    if (pizzaName) {
        const canAddToOven = stepsCompleted(pizzaName);
        if (canAddToOven) { // open if statement
            const pizzaForOven = {
                name: pizzaName,
                timeAdded: Date.now(),
            };
            oven.push(pizzaForOven);
            displayOvenItems();
            clearCanvas();
            completedSteps = [];
        } // close if statement
    }
}
This if statement now wraps our code which pushes pizzas to the oven. Run a quick test in the stepsCompleted function to see if this works:
function stepsCompleted(pizzaName) {
  return true;
}
📝 Remember, a pizza now needs to be clicked on in the "Working on" section before moving into the kitchen.
The pizzas should now be able to add to oven, then change the above to return false to make sure this blocks the pizza from going into the oven.
Finding the steps for the current pizza
This means we can now add some real conditions to test against. For this we need to grab the requiredSteps from our pizzas array. Update the requiredSteps function as follows:
function requiredSteps(pizzaName) {
  // 1. find current pizza from pizzas array, using the find() method
  const pizzaObject = pizzas.find(function (pizza) {
    return pizza.name === pizzaName;
  });
  // 2. store the required steps
  const stepsRequired = pizzaObject.requiredSteps;
}
We now have the stepsRequired, and earlier we also created a variable called completedSteps:
let completedSteps = [];
This variable was added to after each ingredient was clicked on. For the pizza to go into the oven, not only do the completedSteps need to be correct, but also in the same order.
For example, if we have the dough, cheese, and sauce, it technically will match a Margherita, but we don’t want the sauce on top of the cheese, or the dough to be added last.
Comparing our steps with the correct steps
We can check this using the every array method:
function stepsCompleted(pizzaName) {
  const pizzaObject = pizzas.find(function (pizza) {
    return pizza.name === pizzaName;
  });
  const stepsRequired = pizzaObject.requiredSteps;
  // Use the every method to check our steps:
  const checkSteps = stepsRequired.every(function (element, index) {
    return element === completedSteps[index];
  });
}
If you are unsure, this is what we have completed above:
- Loop over the stepsRequired, store the current step into the element variable.
- For each element, we check if it's the same value as the one we store in the completedSteps variable.
- Since element and completedSteps are both arrays, we also need to grab the index number on each loop to compare.
So, first time around, we check if the first element is equal to completedSteps at the zero index, second element we compare with completedSteps index number 1 and so on.
The every method will return true if all of them match, or false if one or more fail. Meaning this is the main test to check if the pizza is correct before going into the oven.
We could just use this and nothing else, but the player will not know exactly what they have done wrong. Have they used too many ingredients, not enough, or the wrong ingredients?
Feedback to the player
To help with this, set up multiple conditions to give different error messages:
function stepsCompleted(pizzaName) {
    const pizzaObject = pizzas.find(function (pizza) {
        return pizza.name === pizzaName;
    });
    const stepsRequired = pizzaObject.requiredSteps;
    const checkSteps = stepsRequired.every(function (element, index) {
        return element === completedSteps[index];
    });
    // check array length to see if too many ingredients have been used
    if (completedSteps.length > stepsRequired.length) {
        console.log("too many");
    }
    // check array length to see if not enough ingredients have been used
    if (completedSteps.length < stepsRequired.length) {
        console.log("not enough");
    }
    // taken correct number of steps, but ingredients are wrong
    if (completedSteps.length === stepsRequired.length && !checkSteps) {
        console.log("wrong ingredients");
    }
}
These messages need to be displayed to the user, and in the index.html page, we have a message area to do this:
<div id="message_area">
  <h3>Messages for the chef</h3>
  <p id="message"></p>
</div>
We could write these messages directly into each if statement, but instead, create a function to handle these to avoid repeated code.
Add this just below stepsCompleted function:
function showErrorMessage(message) {
    // set message to the dom
    document.querySelector("#message").innerText = message;
    // clear message after a time delay
    setTimeout(function () {
        // reset error message
        document.querySelector("#message").innerText = "";
    }, 2000);
}
Displaying error messages
Then call this function in place of the console log's in the stepsCompleted function:
if (completedSteps.length > stepsRequired.length) {
  showErrorMessage(
    "You have used too many ingredients :-(, please try again..."
  );
  return;
}
if (completedSteps.length < stepsRequired.length) {
  showErrorMessage(
    "You have not used enough ingredients :-(, please try again..."
  );
  return;
}
if (completedSteps.length === stepsRequired.length && !checkSteps) {
  showErrorMessage(
    "You have used the wrong ingredients :-(, please try again..."
  );
  return;
}
Again, inside these if statements, we call the wastedPizza function if too many, or the wrong ingredients were used:
if (completedSteps.length > stepsRequired.length) {
  showErrorMessage(
    "You have used too many ingredients :-(, please try again..."
  );
  wastedPizza(); // add
  return;
}
if (completedSteps.length < stepsRequired.length) {
  showErrorMessage(
    "You have not used enough ingredients :-(, please try again..."
  );
  return;
}
if (completedSteps.length === stepsRequired.length && !checkSteps) {
  showErrorMessage(
    "You have used the wrong ingredients :-(, please try again..."
  );
  wastedPizza(); // add
  return;
}
Allowing correct pizzas into the oven
The last step is to add a pizza add to the oven if correct. We also only want to add this to the oven if the oven is not yet full, and earlier we set up variables to check this:
let oven = [];
const ovenCapacity = 6;
In the stepsCompleted function, add a check at the bottom if the function:
function stepsCompleted(pizzaName) {
  // ...
  // check oven is not full before returning true
  if (oven.length < ovenCapacity) {
    return true;
  }
  // otherwise return false (block pizza going to the oven)
  return false;
}
The correct pizza should now add to the oven, if not, the pizza will be wasted or show a message to the user.