0

I'm facing this error when I am trying to loop over an array. Now I know that forEach() only works with arrays, and in my code, I'm using it on .value which is an array. I'm using this website to fetch the data:https://www.icndb.com/api/

Example output when fetching multiple jokes:

{ "type": "success", "value": [ { "id": 1, "joke": "Joke 1" }, { "id": 5, "joke": "Joke 5" }, { "id": 9, "joke": "Joke 9" } ] }

As you can see in my code below, I'm trying to loop over response.value, which seems to me an array. What is it that I'm missing?


function getJokes(e) {
  const number = document.querySelector('input[type="number"]').value;

  const xhr = new XMLHttpRequest();
  xhr.open("GET", `http://api.icndb.com/jokes/random/${number}`, true);
  xhr.onload = function() {
    if(this.status === 200) {
      const response = JSON.parse(this.responseText);
      
      let output = '';

      if(response.type === 'success') {
        response.value.forEach(function(joke){
          output += `<li>${joke.joke}</li>`;
        });
      } else {
        output += '<li>Something went wrong</li>';
      }

      document.querySelector('.jokes').innerHTML = output;
    }
  }
  xhr.send();

  e.preventDefault();
}
  • Be aware that you need to request `http` from `http`. On their `https` they seem to need a new certificate. – Lain Aug 26 '22 at 13:08

3 Answers3

0

Please check whether the response.value type is array or not before the forEach() by using Array.isArray


if (Array.isArray(response.value)) {
  response.value.forEach(function(joke){
          output += `<li>${joke.joke}</li>`;
        });
}

I think this.responseText having no data. So please try this way to make an empty array if that object not having data.

[...response.value].forEach(function(joke){
              output += `<li>${joke.joke}</li>`;
            });

If the above one is working then you need to check the values or some other forEach()

Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
  • But `response.value` is an array! – Rayon Aug 26 '22 at 12:42
  • Please see my updated answer – Ramesh Rajendran Aug 26 '22 at 12:48
  • @Rayon the expected response is an object with a value array but is that what you're getting? Have a look in the dev tools console for errors, and the network tab to see what your request is doing. – Andy Aug 26 '22 at 13:01
  • @Andy - I did execute the code OP shared, it is working fine for me. http://api.icndb.com/jokes/random/5 is returns array for `response.value` – Rayon Aug 26 '22 at 13:27
0

I called the API in the browser and it works and I could get all jokes.

fetch('http://api.icndb.com/jokes/random/5')
  .then(response => response.json())
  .then(data => data.value.forEach(joke => console.log(joke.joke)));

So the problem is not with your forEach method or data. The problem is that your response object seems to be empty or undefined. You need to check your response object and make sure that it is not empty before executing code below.

const response = JSON.parse(this.responseText); <--- here
Sonny49
  • 425
  • 3
  • 18
  • I just realized that I was fetching from the multiple jokes link without inputting a number for the amount of jokes. When inputting a number, it works – Suleyman Eminbeyli Aug 26 '22 at 13:25
0

Your code itself executes fine on http and returns data.


https://api.icndb.com

Their https certificate is expired.

http://api.icndb.com/jokes/random/${number}

You are probably trying to fetch their http address from a https source, which does not work.

Lain
  • 3,657
  • 1
  • 20
  • 27