0

I would like to grab data which has a name tag by calling JSON data by using Ajax. But now a function showCard does not work correctly. How can I get the data which has a name tag? When you click a img which hasfound, I would like to grab data from an API, and show its name by innerHTML. But now nothing happens when you click it. p.s. Its id is added in the function populatePokedex. Hopefully, this question makes sense. Thanks.

(function() {
'use strict';

window.onload = function(){
    populatePokedex(); // <- This works correctly

    var $foundPics = document.getElementsByClassName("found");
    for(var i = 0; i < $foundPics.length; i++){
        $foundPics[i].onclick = showCard;
    }
};



// populate Pokedex
function populatePokedex() {

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "https://webster.cs.washington.edu/pokedex/pokedex.php?pokedex=all");
    xhr.onload = function(){
        if (this.status == 200) {
            var picArr = this.responseText.split("\n");
            for(var i=0; i < picArr.length; i++){
                var eachName = picArr[i].split(":");
                var spriteurl = "/Pokedex/sprites/" + eachName[1];
                var imgClass = 'sprite';
                if(eachName[1]==='bulbasaur.png' || eachName[1]==='charmander.png' || eachName[1]==='squirtle.png'){
                    imgClass += ' found';
                } else {
                    imgClass += ' unfound';
                }
                document.getElementById("pokedex-view").innerHTML += "<img src=\"" + spriteurl + "\" id=\"" + eachName[0] + "\" class=\"" + imgClass + "\">";
            }
        } else {
            document.getElementById("pokedex-view").innerHTML = "ERROR: Status: " + this.status + ", " + this.statusText;
        }
    };
    xhr.onerror = function(){
        document.getElementById("pokedex-view").innerHTML = "ERROR";
    };
    xhr.send();
}


// if the pokemon is found, it shows the data of the pokemon
function showCard() {
    var xhr = new XMLHttpRequest();
    var url = "https://webster.cs.washington.edu/pokedex/pokedex.php?pokemon=" + this.id;
    xhr("GET", url);
    xhr.onload = function(){
        var data = JSON.parse(this.responseText);
        var pokeName = document.getElementsByClassName("name");
        for(var i=0; i < pokeName.length; i++){
            pokeName[i].innerHTML = data.name;
        }
    };
    xhr.onerror = function(){
        alert("ERROR");
    };
    xhr.send();

}


})();

Part of HTML is listed below;

  <div id="my-card">

    <div class="card-container">
      <div class="card">
        <h2 class="name">Pokemon Name</h2>
        <img src="icons/fighting.jpg" alt="weakness" class="weakness" />
      </div>
    </div>
  </div>

  <!-- You populate this using JavaScript -->
  <div id="pokedex-view"></div>
6
  • what happens if you declare data like this: var data = JSON.parse(this.responseText); ? Commented May 8, 2017 at 5:09
  • I tried, but it did not work... Commented May 8, 2017 at 5:13
  • any specifics about what is not working? is showCard method callled? because populatePokedex has async http request inside it. Commented May 8, 2017 at 5:14
  • it looks like you can just get the id inside your click event listener. instead of a for loop to assign click events, use an event listener like this document.querySelector('.found').addEventListener('click', showCard) to assign that listener to every <div class="found"></div> Commented May 8, 2017 at 5:18
  • I tried the code, but the console says there is an error in the code of querySelector... Commented May 8, 2017 at 5:22

3 Answers 3

2

You have a few issues in you JS for showCard

I have coded a simple solution. I added some brief explanations in the code (as comments)

(function() {
  'use strict';

  window.onload = function() {
    populatePokedex(); // <- This works correctly
    
    // adding event listeners to dynamically added nodes.
    document.querySelector('body').addEventListener('click', function(event) {
      // need to target only elements with class found (but unfound would also match the indexOf below, so we changed the name of the matching class slightly)
      if (event.target.className.toLowerCase().indexOf('founded') != -1) {
        showCard();
      }
    });
  };


  // populate Pokedex
  function populatePokedex() {

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "https://webster.cs.washington.edu/pokedex/pokedex.php?pokedex=all");
    xhr.onload = function() {
      if (this.status == 200) {
        var picArr = this.responseText.split("\n");
        for (var i = 0; i < picArr.length; i++) {
          var eachName = picArr[i].split(":");
          var spriteurl = "https://webster.cs.washington.edu/pokedex/sprites/" + eachName[1];
          var imgClass = 'sprite';
          if (eachName[1] === 'bulbasaur.png' || eachName[1] === 'charmander.png' || eachName[1] === 'squirtle.png') {
            imgClass += ' founded';
          } else {
            imgClass += ' unfound';
          }
          document.getElementById("pokedex-view").innerHTML += "<img src=\"" + spriteurl + "\" id=\"" + eachName[0] + "\" class=\"" + imgClass + "\">";
        }
      } else {
        document.getElementById("pokedex-view").innerHTML = "ERROR: Status: " + this.status + ", " + this.statusText;
      }
    };
    xhr.onerror = function() {
      document.getElementById("pokedex-view").innerHTML = "ERROR";
    };
    xhr.send();
  }

  // if the pokemon is found, it shows the data of the pokemon
  function showCard() {
    
    var xhr = new XMLHttpRequest();
    // since you are in a click event, use the target's id instead
    var url = "https://webster.cs.washington.edu/pokedex/pokedex.php?pokemon=" + event.target.id;
    // there was an error here
    xhr.open("GET", url);
    xhr.onload = function() {
      // parse the response text into JSON
      var data = JSON.parse(this.responseText);
      // update the element with this id with a new value from the response data
      document.getElementById("pokemon-name").innerHTML = data.name;
    };
    xhr.onerror = function() {
      alert("ERROR");
    };
    xhr.send();

  }




})();
.founded:hover {
  cursor: pointer;
}

.founded {
  border: 1px solid green;
}
<div id="my-card">

  <div class="card-container">
    <div class="card">
      <h2 id="pokemon-name" class="name">Pokemon Name</h2>
      <img src="https://webster.cs.washington.edu/pokedex/icons/fighting.jpg" alt="weakness" class="weakness" />
    </div>
  </div>
</div>

<!-- You populate this using JavaScript -->
<div id="pokedex-view"></div>

Sign up to request clarification or add additional context in comments.

1 Comment

@Tak I am glad I could help, I added some comments explaining what the issues were
2

When I use your url: https://webster.cs.washington.edu/pokedex/pokedex.php?pokemon=mew, I got this data:

{"name":"Mew","hp":160,"info":{"id":"151","type":"psychic","weakness":"dark","description":"Its DNA is said to contain the genetic codes of all Pokemon."},"images":{"photo":"images\/mew.jpg","typeIcon":"icons\/psychic.jpg","weaknessIcon":"icons\/dark.jpg"},"moves":[{"name":"Amnesia","type":"psychic"},{"name":"Psychic","dp":90,"type":"psychic"}]}

Assuming you want to display the word mew, data.name or data['name'] works fine. What I'm suspecting is that document.getElementsByClassName("name").innerHTML does not exist or something along that line. Could I see the error message that appears when the function is run or show your HTML portion as well?

9 Comments

Thank you for your comment. I added part of my HTML code on the question.
@Tak Can you try something like this var x = document.getElementsByClassName("name"); x[0].innerHTML = data.name;
@Tak , alternatively rather than by class name, if the 'name' is not going to be repeated you could change it to id rather than class.
Thank you. The html is provided, and I cannot modify that... and I'm wondering if 'this.id' in the function showCard is working well. Can I get the id of the element from this.id??
@Tak could you try changing document.getElementsByClassName("name").innerHTML = data.name; to var x = document.getElementsByClassName("name"); x[0].innerHTML = data.name;
|
1

Rather than using the below to declare the "click"

$foundPics[i].onclick = showCard;

You should bind an event listener like this

$foundPics[i].addEventListener('click', showCard());

Aside from this you xhr.open() method is in the wrong place. The standard way of using it is to put it just before your send() call.

Hope this helps

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.