Fetch api sometimes returning undefined

I’m trying to learn fetch and having an odd difficulty. Sometimes I’m getting undefined–maybe 1 in 8 times. It doesn’t get to the catch function, just prints undefined. I tried to make a workaround with a control statement to call the function again if that happens, but it doesn’t seem to do anything. Here’s the api, code below.

const getJokes = () => {
            fetch(jokes)
                .then(response => response.json())

                .then(data => {
                    if (data.setup === undefined) {    //trying to catch the undefined issue
                        console.error("oops")       //this shows up correctly
                        getJokes();                              // this doesn't seem to do anything
                    }
                    setup.innerHTML = data.setup;     //jokes printed in the DOM here
                    delivery.innerHTML = data.delivery;     //and here
                })

                .catch(error => console.log(error))
        }

Fetch API

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

MDN: Checking that the fetch was successful

Not sure if calling the function in a response.ok check will make any difference. I would probably suggest using async/await and then awaiting the retry function call. But it’s a bit dicey to just do a recursive call, if the error never resolves you are just left in an infinite retry loop, so you might want some logic to avoid that.

The API also has some error handling build in.

BTW, what endpoint are you hitting/options are you using? Because I tested it briefly and didn’t get any failures.

1 Like

I don’t really know async/await, so that’s next on my list of things to learn!

BTW here is the code I’m using–it’s a simple thing running on an index.html.

Oh, I see. Not all the joke objects have a setup property. That’s just for the jokes that requirements a setup (Knock knock? Who’s there?).

When using fetch you really do want to check the response, although I’m guilty of sometimes being lazy and not doing it. But that’s just to avoid all the boilerplate in little projects or whatnot. In production code, you really should check it.

Using async/await is pretty easy, in fact, the code looks a lot more like normal synchronous code and you avoid the promise chaining. But I’m not saying using .then() can’t be handy sometimes.

Example code
const getJoke = async () => {
  try {
    const res = await fetch(
      "https://sv443.net/jokeapi/v2/joke/Any?category=Programming"
    );
    if (!res.ok) {
      console.log("status: ", res.status);
      // carful you don't get an infinite loop
      await getJoke();
    }
    const json = await res.json();
    console.log(json);
  } catch (error) {
    console.log("catch error", error);
    // carful you don't get an infinite loop
    await getJoke();
  }
};

getJoke();
1 Like

Thanks for that, I’ve played around with that and it works nicely. Writing await and then calling the function looks so weird to me!

And good job figuring out the “onepart” vs “twopart” thing! I had no clue!

What did you mean by checking the response to fetch? Like consoling out the response object?