0

If that title made no sense, let me elaborate.

I have a two objects one called area and one called enemy.

Each area has it's own enemies so I made enemy prototypes for each area.

Next I did an array.push(); function on each area prototype so if the user clicks a button they'll be shown a list of "area's" they can essentially explore.

the main part that gives me an error is if I try any function like alert(areas[0].enemies[0].name);

How can I use a button to display a specific enemy name?

No jQuery please

function area(name, enemies) {
  this.name = name;
  this.enemies = enemies;
}

function enemy(name, type) {
  this.name = name;
  this.type = type;
}

var cave = new area("Cave", {
  bat: new enemy("Bat", "Flying"),
  snake: new enemy("Snake", "Ground"),
});

var forest = new area("Forest", {
  bear: new enemy("Bear", "Animal"),
  coyote: new enemy("Coyote", "Wolf"),
});

areas = [];
areas.push(cave, forest);

var thatBtn = document.getElementById('thatBtn'),
    display = document.getElementById('display');

thatBtn.addEventListener('click', function() {
  for (i = 0; i < areas.length; i++) {
    var li = document.createElement('li'),
      liBtn = document.createElement('button');
    liBtn.textContent = areas[i].name;
    li.appendChild(liBtn);
    display.appendChild(li);
    liBtn.addEventListener('click', function() {
      for (j = 0; j < areas.length; j++) {
        if (areas[j].name == event.target.textContent) {
          alert(areas[j].name);
          for (k = 0; k < Object.keys(areas[j].enemies).length; k++) {
            alert(areas[j].enemies[k].name);
          }
        }
      }
    });
  }
});

<button id="thatBtn">click here</button>
  <ul id="display">
</ul>
3
  • please take the convention for classes/instantiable functions and use a first upper case letter for the name. Commented Aug 20, 2017 at 8:55
  • as in area, cave, bat, enemy? Commented Aug 20, 2017 at 8:58
  • only for function Area and function Enemy. Commented Aug 20, 2017 at 9:04

4 Answers 4

1

It gives you an error because areas[0].enemies is not an array -- it's an object.

{
    bat: new enemy("Bat", "Flying"),
    snake: new enemy("Snake", "Ground"),
}

Change it to

for(var key in areas[j].enemies) {
    alert(areas[j].enemies[key].name);
}
Sign up to request clarification or add additional context in comments.

1 Comment

so how would I be able to display a specific objects name or type?
0

enemies is an object and not an array, so you need to iterate through keys and fetch from there and not from index, just updated your snippet with that, however the code can be better.

function area(name, enemies){
    this.name = name;
    this.enemies = enemies;
}

function enemy(name, type){
    this.name = name;
    this.type = type;
}

var cave = new area ("Cave", {
    bat: new enemy("Bat", "Flying"),
    snake: new enemy("Snake", "Ground"),
});

var forest = new area ("Forest", {
    bear: new enemy("Bear", "Animal"),
    coyote: new enemy("Coyote", "Wolf"),
});
areas = [];
areas.push(cave, forest);

var thatBtn = document.getElementById('thatBtn'),
    display = document.getElementById('display');

thatBtn.addEventListener('click', function(){
  for(i=0; i < areas.length; i++){
    var li = document.createElement('li'),
        liBtn = document.createElement('button');
    liBtn.textContent = areas[i].name;
    li.appendChild(liBtn);
    display.appendChild(li);
    
    liBtn.addEventListener('click', function(){
      for(j=0; j < areas.length; j++){
        if (areas[j].name == event.target.textContent){
          alert(areas[j].name);
          var keys = Object.keys(areas[j].enemies);
          for(k=0; k < Object.keys(areas[j].enemies).length; k++){
            alert(areas[j].enemies[keys[k]].name);
          }
        }
      }
    });
    
  }
});
<button id="thatBtn">click here</button>
<ul id="display">
</ul>

1 Comment

awesome! thanks!!! and i'm sure the code could be waaay better, as i've only been coding for 2-3 weeks :)
0

add enemies as an array, no need to have them with "named keys" in an object

function area(name, enemies){
    this.name = name;
    this.enemies = enemies;
}

function enemy(name, type){
    this.name = name;
    this.type = type;
}

var cave = new area ("Cave", [
    new enemy("Bat", "Flying"),
    new enemy("Snake", "Ground"),
]);

var forest = new area ("Forest",[ 
    new enemy("Bear", "Animal"),
    new enemy("Coyote", "Wolf"),
]);
areas = [];
areas.push(cave, forest);

var thatBtn = document.getElementById('thatBtn'),
    display = document.getElementById('display');

thatBtn.addEventListener('click', function(){
  for(i=0; i < areas.length; i++){
    var li = document.createElement('li'),
        liBtn = document.createElement('button');
    liBtn.textContent = areas[i].name;
    li.appendChild(liBtn);
    display.appendChild(li);
    
    liBtn.addEventListener('click', function(){
      for(j=0; j < areas.length; j++){
        if (areas[j].name == event.target.textContent){
          alert(areas[j].name);
          
          for(k=0; k < Object.keys(areas[j].enemies).length; k++){
            alert(areas[j].enemies[k].name);
          }
        }
      }
    });
    
  }
});
<button id="thatBtn">click here</button>
<ul id="display">
</ul>

1 Comment

awesome this is exactly what i was trying to accomplish!
0

Your primary issue is here:

for(k=0; k < Object.keys(areas[j].enemies).length; k++){
  alert(areas[j].enemies[k].name);
}

The expression Object.keys(areas[j].enemies) returns an array of object properties, but then you try to iterate over the object using k, not the property name.

Since Object.keys returns a array, you can use array methods so change the loop to:

Object.keys(areas[j].enemies).forEach(function(name) {
  alert(areas[j].enemies[name]);
});

You have a secondary issue that you aren't declaring the counters (i, j and k) used in loops so they become globals when the code runs. Declare them like:

for (var i=0; i < areas.length; i++) {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.