1

I don't know why the code in the snippet below returns this error within the 'generateSkillData' function:

Uncaught TypeError: Cannot read property 'forEach' of undefined
    at generateSkillData (script.js:54)
    at loadingDone (script.js:45)
    at XMLHttpRequest.request.onload (script.js:24)

Rather than displaying the results of skills.json (see below an example of one object):

[
{
    "skill": "Python",
    "description": "An increasingly popular server-side language"
}
] 

I have other code that is very similar and runs fine. I borrowed a lot of the functionality from that code.

function getSkillData(errorFunc, successFunc) {
  let request = new XMLHttpRequest();
  request.open("GET", "js/skills.json", true);
  request.onload = function() {
    if (request.status >= 200 && request.status < 400) {
      console.log("Success! The call worked!");
      const data = request.responseText;

      successFunc(data); {
        console.log("Error: no data available");
      }
    };
    request.onerror = function errorFunc() {
      errorFunc();
    };
  };

  request.send();
}

function loadingDone(data) {
  console.log("LOADING DONE");
  skill_box.innerHTML = "";
  const finished_markup = generateSkillData(data);
  const skill_container = document.getElementById("skill_box");
  skill_container.insertAdjacentHTML("beforeend", finished_markup);
};


function generateSkillData(response) {
  let skill_markup = "";
  response.data.forEach(function(thing) {
    skill_markup += formatSkillData(thing);
  });
  return skill_markup;
}

function formatSkillData(item) {
  const markup = `
        <ul>
            <li>${item.skill}</li>
            <li>${item.description}</li>
        </ul>`;
  return markup;
}

function loadingError() {
  console.log("Error loading skills: try again later");
  document.body.insertAdjacentHTML("beforeend", "<strong>An error occured, please try again later</strong>");
};


(function init() {
  getSkillData(loadingError, loadingDone);
})()
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>

  <form id="user_form">
    <label class="user_input_label" for="link">Skill name:</label>
    <input type="text" name="skill" value="" placeholder="Enter a skill..." id="skill">
    <label class="user_input_label" for="price">Skill description:</label>
    <input type="text" name="description" value="" placeholder="Description..." id="description">
    <input class="submit_button" type="submit" value="Submit">
  </form>

  <section id="skill_box">

  </section>

</body>

<script src="js/script.js"></script>

</html>

3
  • response in generateSkillData is a string Commented Dec 30, 2017 at 11:46
  • What is with this syntax: successFunc(data); { console.log("Error: no data available"); } ? Commented Dec 30, 2017 at 11:46
  • Not sure, actually, sorry Commented Dec 30, 2017 at 11:49

2 Answers 2

1

You have to parse your response to JSON.

JSON.parse(response);

Insert it just before the for each call. That way you could iterate over it and get the specific objects.

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

Comments

0
const data = JSON.parse(request.responseText);  

Added JSON.parse here after utilising console.log on response

function generateSkillData(response){
    let skill_markup = "";
    console.log(response);
    response.forEach(function (thing) {
        skill_markup += formatSkillData(thing);
    });
    return skill_markup;
}

After utilising console.log, I figured out how to do it

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.