0

Not sure what to write as a title, but this is my problem:

  if(selectedCountry=="India"){
    stateArray=[]
    Object.keys(jsonObj.India).forEach(function(k) {
      stateArray.push(k)
    });
  }

  if(selectedCountry=="USA"){
    stateArray=[]
    Object.keys(jsonObj.USA).forEach(function(k) {
      stateArray.push(k)
    });
  }
  if(selectedCountry=="UK"){
    stateArray=[]
    Object.keys(jsonObj.UK).forEach(function(k) {
      stateArray.push(k)
    });
  }
  if(selectedCountry=="none"){
    stateArray=[]
  }
  for (var i=0; i<stateArray.length; i++){
    var stateOption = new Option(stateArray[i],stateArray[i])
    if (states.length<stateArray.length+1){
      states.appendChild(stateOption);

    }

Although the code is working, it is bad way of doing it. Is there a way where I rewrite the code so I don't need the if statements? Because selected country is a string, I cannot use:

 Object.keys(jsonObj.selectedCountry).forEach(function(k) {
      stateArray.push(k)
    });

Is there any way around it? Thx

user3799968
  • 1,117
  • 2
  • 8
  • 14

2 Answers2

0

Two factors:

  1. Reduce duplication; for all eventualities, stateArray begins as an empty array, so declare that once. If country is none, it remains just an empty array.

  2. To reference a key/property dynamically, use square-bracket syntax rather than dots

    stateArray = [];
    if(selectedCountry !== "none")
        Object.keys(jsonObj[selectedCountry]).forEach(function(k) {
            stateArray.push(k)
        });
    
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Mitya
  • 33,629
  • 9
  • 60
  • 107
  • 1
    There's absolutely no need to use `.forEach` and `.push` here - the desired array _is_ the `Object.keys` – Alnitak Mar 17 '16 at 12:25
  • Well I just carried that across from the question, since it was not the focus of the question, which was, rather, how to omit the conditionals and how to reference dynamic properties. – Mitya Mar 17 '16 at 12:26
  • Sure, but why use 5 lines when one will do (and avoiding the repeated function callbacks in the process) ? – Alnitak Mar 17 '16 at 12:27
0

This would be the correct approach. There is no reason to create an array then create the options. Simply create the options as you read the object's keys.

var geographicalData = getGeoData();
var countrySelect = document.getElementById('country');

populateCombo(countrySelect, geographicalData);

countrySelect.addEventListener('change', function(e) {
  var stateSelect = document.getElementById('state');
  stateSelect.options.length = 0;                       // Empty values.
  var selectedCountry = e.target.value;
  
  if (geographicalData[selectedCountry]) {
    populateCombo(stateSelect, geographicalData[selectedCountry]);
  }
});

countrySelect.dispatchEvent(new CustomEvent('change')); // Trigger change.

function populateCombo(combo, obj) {
  var keys = Object.keys(obj).sort();
  for (var i = 0; i < keys.length; i++) {
    var option = new Option(keys[i], keys[i]);
    combo.appendChild(option);
  }
}

function getGeoData() {
  return {
    "India" : {
      "Maharashtra" : 1,
      "Tamil Nadu" : 1,
      "Uttar Pradesh" : 1,
      "West Bengal" : 1,
      "Gujarat" : 1,
      "Karnataka" : 1,
      "Rajasthan" : 1,
      "Andhra Pradesh" : 1,
      "Madhya Pradesh" : 1,
      "Delhi" : 1
    },
    "USA" : {
      "California" : 1,
      "Florida" : 1,
      "New York" : 1,
      "Texas" : 1,
      "Hawaii" : 1,
      "Washington" : 1,
      "Colorado" : 1,
      "Virginia" : 1,
      "North Carolina" : 1,
      "Arizona" : 1
    },
    "UK" : {
      "South West" : 1,
      "East of England" : 1,
      "South East" : 1,
      "East Midlands" : 1,
      "Yorkshire and the Humber" : 1,
      "North West" : 1,
      "West Midlands" : 1,
      "North East" : 1,
      "London" : 1,
      "Scotland" : 1,
      "Wales" : 1,
      "Northern Ireland" : 1
    }
  };
}
<select id="country"></select>
<select id="state"></select>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132