0

I am newbee and this is my first if and else statement.

I am trying to make the user enter a name of animal based on the sounds he or she sees on the page. New sounds are generated on refresh through an array.(this part worked fine)

The issues I am facing:

  1. If I ADD my checkGuess function, then my makeSound function does not work.

  2. Is my if and else condition wrong or my logic? I want to compare what the user entered with the array and then show an alert accordingly.

Would appreciate some guidance.

<script>
    function start() {
        makeSound();
    }

    window.onload = start;

    function makeSound() {
        // Used Variable to define an Array for storing different sounds 
        var sounds = ["moo", "woof"];

        // Used the Math function in JS to create a random sound and assign new variable 
        var rand1 = Math.floor(Math.random() * sounds.length);

        // below var is defined to hold the sound
        var soundDisplay = sounds[rand1];

        // display logic
        var soundElement = document.getElementById("soundDisplay");
        soundElement.innerHTML = soundDisplay;
    }

    function checkGuess() {
        var button = document.getElementById("butAnimal");
        var usrInput = document.getElementById("guess").value;

        //Get the value of the input field with id="guess"
        if (usrInput == "Cow" && sounds[0]) {
            alert("Congratulations you got the sound right.");
        } else if (usrInput == "Dog" && sounds[1]) {
            alert("Congratulations you got the sound right.");
        }
    }

    //console.log("here");
</script>
<html>
    <head></head>
    <body>
        </br></br>
        The user has to enter the name of the animal based on the sounds like woof and moo which are inside an array.</br>
        </br></br>

        <form>
            What animal says <span id="soundDisplay"></span> 
            <input type="text" id="guess" name="guess">
            <input type="button" onclick="checkGuess()" id="butAnimal" name="butAnimal" value="Submit">
        </form>
        <p id="result"></p>
    </body>
</html>
talemyn
  • 7,822
  • 4
  • 31
  • 52

1 Answers1

0

There's an error thrown due to sounds being a scoped (or private) variable to your makeSound function.

Move it out of the function and it will work. Here's a fiddle demonstrating: http://jsfiddle.net/akx19Loq/

A bit more on variable scope (from MDN)

When you declare a variable outside of any function, it is called a global variable, because it is available to any other code in the current document. When you declare a variable within a function, it is called a local variable, because it is available only within that function.

EDIT

Hi Vipul,

Sure, I'll be happy to explain! Let's break down what happened in our checkGuess logic.

We get the user's input and store it as a variable, usrInput.

var usrInput = document.getElementById("guess").value;

We then check to see if the usrInput variable matches either "Cow" or "Dog". There is also an additional check for either sounds[0] or sounds[1]. These are required because an animal must be associated with the sound (a cow can only "moo", and a dog can only "woof").

if (usrInput == "Cow" && sounds[0]) {
    // Handle correct guess
}

However, there is an issue with the check && sounds[0] (which is "moo"), will always evaluate true (due to how JavaScript evaluates booleans - that is, 0, false, null, and undefined are all false/falsey, but 1, true, "yes", or [] are true/truthy - which you seem to understand from your comments regarding == and ===).

So, if the question was "What animal says woof", and you guess "Cow", you will win because usrInput IS definitely equal to Cow, and sounds[0] (or woof) is always true. So we need to add an additional check. That's why we add:

var sound = document.getElementById("soundDisplay").textContent

The animal sound is determined from makeSound. However, we don't store the sound in a place that is accessible to our checkGuess function (this is related to "scope" in JavaScript), we need to get the value of the sound from the span element (using textContent - I could have used innerHTML, but textContent makes more sense here...)

Now that we have the sound, we can properly check for the question "What animal says woof". When a user guesses "Cow", the usrInput == "Cow" will still be true, but sounds[0] == sound will evaluate to false since "moo" does not equal "woof".

Hopefully this explains why both checks are required in the if AND else statement. As for why three (===), you're definitely correct - type is not involved here, but === is considered good practice to follow when writing JavaScript (nothing to do with array, just the truthy/falsey aspect of JavaScript).

As for developing your answers - you nailed it right on the head! Practice is definitely key! I would recommend you continue reading your book, and be aware of the following books: http://eloquentjavascript.net/ (Free to read online, available in book form - great book to start with as a newbie) and Professional JavaScript for Web Developers (By Zakas). In addition, Crockford's "JavaScript, The Good Parts" is always a recommended resource (Personally, it wasn't until this book that I switched from == to === for all comparisons, not just when I needed to do a value and type check.)

Also, be sure to understand how the console works! Check out: https://developer.chrome.com/devtools/docs/console to learn more about this. The console, along with reading Eloquent JavaScript, will allow you to participate as you read.

Another tip - Continue participating in StackOverflow! As you're learning, use stackoverflow as a resource. Read other people's questions and try to answer them (even if you don't submit your answer). If you can't find the solution, see what others did and try to understand how their answers work. Ignore the "gamification" aspect of stackoverflow (getting an answer accepted is always nice, but learning from experienced developers is way more beneficial to you as developer!)

Finally, take up a personal project on something you're passionate about! Your passion will fuel your desire to continue learning the technology.

BTW, Here's a refactored version of your game logic with comments:

http://jsfiddle.net/qadnyt6d/

/* The following randomly selects an animal and returns animal object,
   assigning to the variable "selectedAnimal"

   Note the paranthesis around the function and at the end,
   or (function(){})();

   This is an immediately invoked function expression, or IIFE.

   As you continue to learn, you will soon see how powerful this is!
   http://stackoverflow.com/questions/6340874/a-javascript-function
*/

var selectedAnimal = (function() {

    // Array of animals
    var animals = [
        {
            name: 'dog', says: 'woof'
        },
        {
            name: 'cow', says: 'moo'
        },
        {
            name: 'cat', says: 'meow'
        }
    ];

    // Return randomly selected animal
    return animals[Math.floor(Math.random() * animals.length)];
})();

// Event handler bound to button
function checkUserInput() {

    var usrInput = document.getElementById('guess').value;

    // We construct a new Regular Expression to test.
    // The 'i' denotes case-insensitive, so 'Cat' and 'CAT'
    // and 'cat' are all matched

    var regex = new RegExp(selectedAnimal.name, 'i');

    if (regex.test(usrInput)) {
        alert('Congrats! You guessed the right animal!');   
    } else {
        alert('Sorry, that is not correct!');   
    }

}

// Bind window onload event listener, updates span in HTML with correct animal name
window.onload = function() {

    // Display in DOM
    document.getElementById("soundDisplay").innerHTML = selectedAnimal.name;

}

Good luck Vipul!

BTW, Here's a challenge for you - can you take the new version and refactor the code so that after a user wins, a new game begins?

Jack
  • 9,151
  • 2
  • 32
  • 44
  • Thanks Jack. I made the var global but it still does not work and I dont see any error. So does that mean my logic is wrong – Accidental_Everything Feb 26 '15 at 21:14
  • @Vipul - Where is your ` – Jack Feb 26 '15 at 21:43
  • The script tags are located in the head section. – Accidental_Everything Feb 27 '15 at 03:51
  • @Vipul - Here's an updated fiddle that's an exact copy of your pasted code: http://jsfiddle.net/akx19Loq/1/ - The only thing I changed was moving sounds outside of the function. Does that fiddle work for you?? – Jack Feb 27 '15 at 04:51
  • No I am sorry it does not work. I tried in IE and Chrome. This is first time in fiddle. (I am just entering dog on the right hand panel result panel ) Ie throws error like LOG: InterYield clickbind 1.0-SNAPSHOT.34,044 20150226-1458 LOG: using IframeBackTracker LOG: Keywords Edit fiddle LOG: IE version 9 – Accidental_Everything Feb 27 '15 at 16:23
  • Hey @Vipul, are you entering "dog" or "Dog" - the logic is checking for "Dog" (case matters). If you wanted to test any case, you could update the logic with a regex check like `/cow/i`. I did realize ONE issue you had - that is the check of `&& sound[n]` doesn't actually do anything (so in the previous fiddle, both answers of "Dog" and "Cow" will alert - although it may just be Dog... Here's an updated fiddle that addresses this: http://jsfiddle.net/akx19Loq/2/ – Jack Feb 27 '15 at 22:29
  • Thank you so much Jack. I am going through the code to understand it. When you get time can you pl explain why you wrote this 1) var sound = document.getElementById("soundDisplay").textContent; (Line 32) 2) Also you compared it in the If and Else statement 3) why three equal. (compare equal value and type. How is type involved here. is it because of the array. can you expand more on this) 4) can you pl explain the if statement in simple english. (sorry did not get that) – Accidental_Everything Feb 28 '15 at 15:14
  • Overall some stupid quesitons . 1) how do develop my logic. (is Practice, practice !! the answer) 2) How do I know these syntax exists. (like /dog/i or .textContent) 3) Currently I am reading Head First HTML and Javascript and reading W3 schools. Can you recommend some resource book or other wise. Basically I want to read about a topic and then instantly do a small project and build on that. Is this the way to work. I am a designer and this is my first programming / logic class Would appreciate your help a lot Vipul – Accidental_Everything Feb 28 '15 at 15:15
  • @Vipul No stupid questions when it comes to JavaScript, haha. Edited my answer to address your comments. Good luck! – Jack Mar 01 '15 at 02:52
  • Thanks a lot Jack. You are kind with generous with your time. I am going through this and the resources and would surely try that challenge. – Accidental_Everything Mar 01 '15 at 14:54
  • Hi Jack. I want to ask you something about my upcoming project. Do you think a web form is a good project to integrate most of the below Objects, Functions Arrays Variables Built-in functions Loops If/Else statements DOM/Elements – Accidental_Everything Mar 10 '15 at 17:08
  • OR would you recommend looking at Game. Can you point me to a simple game that I can try. The reason I started to think about form was that online you see them the most and they are mission critical I have designed form in the past but never coded them. – Accidental_Everything Mar 10 '15 at 17:12