0

Hope this isn't too much of a repeating question, I've checked around seen similar but can't seem to solve my issue.

I have a JS object:

var option1Data = {
    option: 'Yes',
    numberOfPeople: 3,
    gender: {} ,
    region: {}
};

I want to check if an item is in gender, if not add and set to 1 else increment into. Note that appending it in is important.

Can someone kindly tell me whats wrong:

var input = 'female';    //for purposes of this example

var processGender = function(input) {

    if(option1Data['gender'].hasOwnProperty(input)) {
        option1Data['gender'][input]++;
    }else {
        option1Data['gender'][input] = 1;
    }
};

User.find({_id: item['userID']}, {gender: 1, country:1}, function(req, foundUser) {
    processGender(foundUser[0]['gender']);
});
cviejo
  • 4,201
  • 15
  • 27
userMod2
  • 5,924
  • 9
  • 38
  • 81
  • 1
    Nothing is wrong really. That code does exactly what you decribed..unless you're creating / passing a new object everytime, it should do exactly that. – cviejo Feb 14 '16 at 18:49
  • 1
    This code works - what exactly is your problem? – Nick Zuber Feb 14 '16 at 18:51
  • I don't understand what you are incrementing if the value is supposed to be a string – Gabs00 Feb 14 '16 at 18:51
  • The value is clearly not supposed to be a string...@userMod2 can you post your full code? – cviejo Feb 14 '16 at 18:52
  • @NickZuber so when i check the resulting object the gender {} remains empty. @Gabs00 i set it to be 1 then would be incrementing every other time its found. Infact even i comment out that bit, its still not giving me `gender: {female: 1} – userMod2 Feb 14 '16 at 18:53
  • 1
    Post your full code, please. The code above works, your error is somewhere else. – cviejo Feb 14 '16 at 18:54
  • I see whats happening now, blew my mind for a bit – Gabs00 Feb 14 '16 at 18:56
  • Agreed with @cviejo - the code you've posted works fine, your error must lie somewhere else or how you're trying to use it – Nick Zuber Feb 14 '16 at 18:56
  • @cviejo have shown full code in question – userMod2 Feb 14 '16 at 19:00
  • Can you log what's being passed to `processGender`, the `input` variable? – cviejo Feb 14 '16 at 19:05
  • Finally after 2 hours got it! The answer below essentially explains it. Code as everyone here has confirmed was correct. I stupidly was checking with a console.log output in the wrong place - which naturally wouldnt guarantee to have the updated value. Ahhhhh!! But thanks everyone and happy to have understood! – userMod2 Feb 14 '16 at 19:33
  • Cool. Next time please post the code including the logs. Also, the answer below marked as correct is referring to something completely unrelated to the problem. – cviejo Feb 14 '16 at 19:36
  • Agreed @cviejo will do. Apologies i didnt notice myself, feel bad had to bother. But its appreciated. – userMod2 Feb 14 '16 at 19:43
  • *Where* and *when* are you not getting `gender: {female: 1}`? Notice that `find` is asynchronous! – Bergi Feb 14 '16 at 21:35

2 Answers2

1

You can't guarantee property order if using an object, you can see this stackoverflow answer for that : Does JavaScript Guarantee Object Property Order?

So appending is out of the question for the structure you're using. But maybe something like below would work for you :

var maleGenderObject= { gender : "male" , count : 0 };
var femaleGenderObject = {gender : "female" , count : 0 };
var option1Data = { option: 'Yes',
    numberOfPeople: 3,
  gender: [] ,
  region: {} };

Then when adding , you can do something like :

var input = "female";
//Nothing exists at the moment, so add the proper object, I added both since there are only two, but you can modify for more genders, but logic will be a bit more complex
if ( option1Data.gender.length == 0 ){
    if (input == "female" ){
        option1Data.gender.push(femaleGenderObject);
        option1Data.gender.push(maleGenderObject); 
    }
    else {
        option1Data.gender.push(maleGenderObject); 
        option1Data.gender.push(femaleGenderObject); 
    }
}
//If both gender objects exist, determine which one you want, and increment its count
if (option1Data.gender[0].gender == input){
    option1Data.gender[0].gender.count++;
}
else {
    option1Data.gender[1].gender.count++;
}

This definitely can be optimized, but it's really two variables so I think simple straightforward is better in this case

Another way is to have your gender objects have an order property, and you can use that.

Community
  • 1
  • 1
jay
  • 497
  • 4
  • 16
0

Your code is working fine:

var option1Data = {
        option: 'Yes',
        numberOfPeople: 3,
        gender: {},
        region: {}
    },
    input = 'female';

if (option1Data['gender'].hasOwnProperty(input)) {
    option1Data['gender'][input]++;
} else {
    option1Data['gender'][input] = 1;
}        

document.write('<pre>' + JSON.stringify(option1Data, 0, 4) + '</pre>');
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324