Orbital676
Orbital676

Reputation: 65

How can I key and value to same object on repeated clicks

I apologise if this question is basic or not asked properly. I have been searching the site for hours to try and get a fix...

I am trying to make a guessing game. On grabbing the dropdown value on submit, I check the grabbed value against the key from another array object (theComputer[i]). If there is a matching property, and its value is true, add the key and value to compTempObj{}. Then on repeated dropdown submits, repeat the above process, each time adding the matching property & value to the same compTempObj{}. It does almost work except, it adds a new object for each click, rather than to the same Object.

The dropdown:

<select class="featureList">
<option class="charFeature">male</option>
<option class="charFeature">female</option>
<option class="charFeature">black hair</option>
<option class="charFeature">white hair</option>
<option class="charFeature">blonde hair</option>
<option class="charFeature">red hair</option>
<option class="charFeature">blue hair</option>
<option class="charFeature">purple hair</option>
<option class="charFeature">beard</option>
<option class="charFeature">moustache</option>
<option class="charFeature">glasses</option>
<option class="charFeature">earrings</option>
<option class="charFeature">hat</option>
<option class="charFeature">green eyes</option>
<option class="charFeature">black eyes</option>
</select>

My JS:

//Get SELECT values
function grabInputVal() {
    // click event on <select> submit
    $(".pickAFeatureBtn").on('click', function(e) {
        e.preventDefault();
        // Assign <select> value to var
        var computerHas = ($(".featureList").val());
        theComputer;
        //check theComputer array for computerHas(select) property
        for (var i = 0; i < theComputer.length; i++) {
            // line below check for property val from dropdown against theComputer 
            if (theComputer[i].hasOwnProperty(computerHas) && theComputer[i][computerHas] === true) {
                var compTempObj = {};
                // compTempObj.prop = computerHas;
                compTempObj[computerHas] = theComputer[i][computerHas];
                compTempArr.push(compTempObj);
                console.log(compTempArr);
            } else {
                // Run function to make computer guess will go here
                console.log('Noooooooooo!');
            }
        }
    });
}

Upvotes: 0

Views: 65

Answers (4)

joe_coolish
joe_coolish

Reputation: 7259

The problem is that the scope of compTempObj is local to the click event handler. On every click it gets created because its definition is in the click function:

for (var i = 0; i < theComputer.length; i++) {
    // line below check for property val from dropdown against theComputer 
    if (theComputer[i].hasOwnProperty(computerHas) && theComputer[i][computerHas] === true) {


        // THIS VARIABLE IS LOCAL SCOPE!!  
        // Move the definition up higher to have a larger scope
        var compTempObj = {};


        // compTempObj.prop = computerHas;
        compTempObj[computerHas] = theComputer[i][computerHas];
        compTempArr.push(compTempObj);
        console.log(compTempArr);
     } else {
        // Run function to make computer guess will go here
        console.log('Noooooooooo!');
     }
}

I'm confused about compTempArr. It doesn't have a definition so I don't know the scope of that variable.

If you want to reuse compTempObj, put its scope up higher, or make it a global variable.

EDIT

If compTempArr is global, you can do the following and reuse compTempObj

for (var i = 0; i < theComputer.length; i++) {
    // line below check for property val from dropdown against theComputer 
    if (theComputer[i].hasOwnProperty(computerHas) && theComputer[i][computerHas] === true) {


        // THIS VARIABLE IS LOCAL SCOPE!!  
        // Move the definition up higher to have a larger scope
        var compTempObj = compTempArr[0] || {};


        // compTempObj.prop = computerHas;
        compTempObj[computerHas] = theComputer[i][computerHas];

        if(compTempArr.length === 0)
            compTempArr.push(compTempObj);
        console.log(compTempArr);
     } else {
        // Run function to make computer guess will go here
        console.log('Noooooooooo!');
     }
}

What I'm doing is pushing the compTempObj onto the compTempArr as the first property. IDK if you're using compTempArr for anything else, but since it is globally scoped, you can do that. HOWEVER!! I recommend doing the following:

  • Rename your variables so that they explain what you're trying to do or what they describe. temp is a TERRIBLE naming practice, don't do it!
  • Define your game data as a single object and have that object be globally scoped. That way your game logic can access the game data and not worry about scoping.
  • Define your functions as named functions and pass them into the event handlers. That way you can organize your game logic in one place, and not have your game logic and your game setup all mixed together.

Good luck!

Upvotes: 1

Vishal Kumar Sahu
Vishal Kumar Sahu

Reputation: 1396

Hope it helps you to get into right direction-

  1. var computerHas = ($(".featureList").val()); gives you an array so what value are you referring? (Check if you wanna use $(".featureList").each(function(){}))
  2. var compTempObj is overwritten each time you call the function. Hence is it new everytime.

Possibly you should use-

var YourVariable;
// Since it is defined outside the function value will not be overwritten each time function is called

    function your_function(){
        ............YOUR CODE ..........

        // YourVariable = AssignNewValue

        ............MORE CODE ..........
    }

Upvotes: 0

dinologic
dinologic

Reputation: 64

Unless I'm totally missing something I think the answer is to simply move the variable declaration outside of the function. You're re-creating the object every time the click event executes. So instead of...

$(".pickAFeatureBtn").on('click', function(e) {
    ...
    var compTempObj = {};
    ...
}

...do...

var compTempObj = {};
$(".pickAFeatureBtn").on('click', function(e) {
    ...
}

Depending on the scope of the grabInputVal function you may need to put it outside of that though.

Also, as Plaimanus Lueondee pointed out, you're option tags need a value attribute. Or just use the text of the selected option like so...

$(".featureList option:selected").text();

Upvotes: 0

Plaimanus Lueondee
Plaimanus Lueondee

Reputation: 43

in each options you probably need to add value attribute to it.

<select class="featureList">
  <option class="charFeature" value="male" >male</option>
  <option class="charFeature" value="female" >female</option>
  <option class="charFeature" value="black hair" >black hair</option>
  ....
</select>

then var computerHas = ($(".featureList").val()); you will get the value of your option :)

Upvotes: 0

Related Questions