Zeo
Zeo

Reputation: 11

Uncaught TypeError: Cannot read property 'name' of undefined at XMLHttpRequest.xmlhttp.onload

I'm trying to pull info from a JSON file into JavaScript and then to an HTML page but it keeps erroring when I get to a for loop that takes info from said file.

 function digiLevel() {
             document.getElementById("digivice").innerHTML = "Loading...";

                    var xmlhttp = new XMLHttpRequest();
                    xmlhttp.onload = function() {
                        if (xmlhttp.status == 200) {
                            var textBox = document.getElementById("digivice");

                              var output1 = "";
                              var output2 ="";
                              var output3 = "";        
                              var digimon = xmlhttp.responseText;

                            console.dir(digimon);
                            digimon = JSON.parse(digimon);
                            console.dir(digimon);

                            output1 = "<ul>";
                            for (i = 0; i < 6; i++) {
                                output2 += "<li>" + digimon[i].name + " is a(n) " + digimon[i].level + "</li><br>";
                            }
                            output3 = "</ul>";

                            textBox.innerHTML = output1 + output2 + output3;
                        }
                    }
                    xmlhttp.open("GET", "http://ec2-54-158-64-221.compute-1.amazonaws.com/Challenge9/webService.php?content=data&format=json", true);
                    xmlhttp.send();
                }

And it returns the Uncaught TypeError on the line

 output2 += "<li>" + digimon[i].name + " is a(n) " + digimon[i].level + "</li><br>";

I don't see how 'name' is undefined?? Maybe I'm just blind; it's 1AM here.

EDIT:

Thanks for the guiding comments; I was able to find my error:

digimon by itself didn't have a name tag of its own even with an index variable, and so I accessed the name tag by

    digimon.digivice.digimon[i].name

after returning digimon to the console to analyze its contents. I'm still new to working with JSON/XML so if there is a faster/more efficient/effective way to achieve the same result, do please let me know!

Upvotes: 1

Views: 2536

Answers (3)

Krishna Wadhwani
Krishna Wadhwani

Reputation: 123

let fetchbtn = document.getElementById('fetchbtn');
let popbtn = document.getElementById('populate');
fetchbtn.addEventListener('click', buttonClickHandler)
popbtn.addEventListener('click', pophandler)

function buttonClickHandler() {
  console.log('You Have Clicked The Fetch Button')
  //Create XHR Object
  const xhr = new XMLHttpRequest();
  //Open The Object
  xhr.open('POST', 'http://dummy.restapiexample.com/api/v1/create', true);
  xhr.getResponseHeader('Content-type', 'application/json')
  //What To Do On Progress
  xhr.onprogress = function() {
    console.log('On Progress')
  }
  // xhr.onreadystatechange = function (){
  //     console.log('ready state', xhr.readyState)
  // }
  //Response Is Ready
  xhr.onload = function() {
    if (this.status === 200) {
      console.log(this.responseText)
      console.log('We are done')

    } else {
      console.error('Some Error Occoured')
    }
  }
  //Send Data
  params = `{"name":"Krishna","salary":"210000","age":"1234568945465"}`;
  xhr.send(params)

}

function pophandler() {
  console.log('You Have Just Clicked The Populate Handler')
  const xhr = new XMLHttpRequest()
  xhr.open('GET', 'ajax.json', true)
  xhr.getResponseHeader = ('Content-type', 'application/j-son')
  xhr.onprogress = function() {
    console.log('Loading Pop')
  }
  xhr.onreadystatechange = function statechange() {
    console.log('Current Loading State Is ', xhr.readyState)
  }
  xhr.onload = function() {
    if (this.status === 200) {
      let obj = JSON.parse(this.responseText)
      console.log(obj)
      let list = document.getElementById('list');
      str = "";
      for (i in obj) {
        str += `<li>${obj[i].name}</li>`;
      }
      list.innerHTML = str;
      console.log('We Are Done')
    } else if (this.status === 429) {
      console.error('To Many Requests')
    } else {
      console.error('Some Error Occoured')
    }

  }

  xhr.send()
}
// http://dummy.restapiexample.com/api/v1/employees
<!doctype html>
<html lang="en">

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
      <a class="navbar-brand" href="#">Navbar</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="#">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Link</a>
          </li>
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                  Dropdown
                </a>
            <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
              <li><a class="dropdown-item" href="#">Action</a></li>
              <li><a class="dropdown-item" href="#">Another action</a></li>
              <li>
                <hr class="dropdown-divider">
              </li>
              <li><a class="dropdown-item" href="#">Something else here</a></li>
            </ul>
          </li>
          <li class="nav-item">
            <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
          </li>
        </ul>
        <form class="d-flex">
          <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
          <button class="btn btn-outline-success" type="submit">Search</button>
        </form>
      </div>
    </div>
  </nav>
  <title>Hello, AJAX</title>
</head>

<body>
  <div class="container my-4">
    <h1>AJAX Tutorial</h1>
    <button type="button" id="fetchbtn" title='Fetch Data' class="btn btn-primary">Write Data</button>
    <button type="button" id="populate" title='Populate Data' class="btn btn-success">Fetch Data</button>

    <ul id="list">
      <h1></h1>
    </ul>
  </div>
  <!-- Optional JavaScript; choose one of the two! -->

  <!-- Option 1: Bootstrap Bundle with Popper -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
  <script src="ajax.js"></script>
  <!-- Option 2: Separate Popper and Bootstrap JS -->
  <!--
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" crossorigin="anonymous"></script>
    -->
</body>

</html>

Upvotes: -1

xianshenglu
xianshenglu

Reputation: 5319

change this:

digimon = JSON.parse(digimon);

to:

digimon = JSON.parse(digimon).digivice.digimon

according to your code :

xmlhttp.open("GET", "http://ec2-54-158-64-221.compute-1.amazonaws.com/Challenge9/webService.php?content=data&format=json", true);

and better change this:

for (i = 0; i < 6; i++) {

to

for (let i = 0; i < digimon.length; i++) {

Upvotes: 2

gurvinder372
gurvinder372

Reputation: 68393

And it returns the Uncaught TypeError on the line

 output2 += "<li>" + digimon[i].name + " is a(n) " + digimon[i].level + "</li><br>";

Not sure why you have hard-coded your for-loop as

for (i = 0; i < 6; i++) { //where is 6 coming from

Looks like somewhere during the iteration, digimon[i] doesn't exists (is undefined), so make your for-loop condition as

for (i = 0; i < digimon.length; i++) { //where is 6 coming from

Upvotes: 2

Related Questions