skip to Main Content
let url = "https://v2.jokeapi.dev/joke/Programming,Miscellaneous,Dark,Pun,Spooky?blacklistFlags=nsfw,religious,political,racist,explicit";

let btn = document.querySelector("button");
let result = document.querySelector("#result"); // Moved result selection outside the click event listener

btn.addEventListener("click", async () => {
    let joke = await getJokes();
    result.innerText = joke.setup; // Display setup immediately
    // setTimeout(() => {
        result.innerText += "n" + joke.delivery; // Append delivery after 3 seconds
    // }, 4000);
});

async function getJokes() {
    try {
        let res = await axios.get(url);
        let setup = res.data.setup;
        let delivery = res.data.delivery;
        
        return { setup, delivery }; // Return both setup and delivery as an object
        
    } catch (e) {
        console.log("Sorry! Got some error");
        return { setup: "No Joke found", delivery: "" };
    }
};
body {
  font-family: Arial, sans-serif;
  background-color: #f7f7f7;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  width: 400px;
  text-align: center;
  padding: 20px;
  border: 2px solid #333;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
}

.btns {
  background-color: #3498db;
  color: white;
  border: none;
  cursor: pointer;
  font-size: 1.2rem;
  padding: 10px 20px;
  border-radius: 5px;
  transition: background-color 0.3s ease;
}

.btns:hover {
  background-color: #2980b9;
}

#result {
  margin-top: 20px;
  font-size: 1.2rem;
  line-height: 1.5;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Joke Teller</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <p id="result"></p>
       <button class="btns">Tell me A Joke</button>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.4.0/axios.min.js"></script>
    <script src="script.js"></script>
</body>
</html>

Problem Description: I am developing a basic web app that retrieves jokes from an external API and displays them in sequence, starting with the setup and followed by the punchline after a delay. Unfortunately, I’m having an issue where the output sometimes contains undefined values. I need some help resolving this problem.

Issue Details:
On my web application, I have a "Tell me A Joke" button that fetches jokes from an external API. The jokes are displayed in two parts – first, the setup, and then the delivery, with a delay of 5 seconds. However, I have noticed that after a few jokes, the delivery section displays undefined. This unexpected behaviour is affecting the user experience.

Additional Notes:
I am not exceeding the limit of 120 requests per minute. Here is the link to the API doc

2

Answers


  1. You could simply test for the existence of the .joke property and if it does not exist, simply process the .setup and .delivery properties instead.

    fetch("https://v2.jokeapi.dev/joke/Programming,Miscellaneous,Dark,Pun,Spooky?blacklistFlags=nsfw,religious,political,racist,explicit").then(r=>r.json())
    .then(o=>console.log(o.joke??o.setup+"n"+o.delivery))
    Login or Signup to reply.
  2. About the undefine Values. The Json from your API can come in two types, ‘twopart’ that have both setup and delivey and ‘single’ that only have the joke. Your undefined value comes when your API returns a ‘single’ and as you call res.data.setup return value is going to be undefined as your program couldn’t find the .setup.

    In order to Fix a putted a swith that return diferent values depending in the Json Retrived.

    let url = "https://v2.jokeapi.dev/joke/Programming,Miscellaneous,Dark,Pun,Spooky?blacklistFlags=nsfw,religious,political,racist,explicit";
    
    let btn = document.querySelector("button");
    let result = document.querySelector("#result"); // Moved result selection outside the click event listener
    
    btn.addEventListener("click", async () => {
        let joke = await getJokes();
        switch(joke.JokeType){
            case 'twopart':
                result.innerText = joke.setup; // Display setup immediately
                // setTimeout(() => {
                    result.innerText += "n" + joke.delivery; // Append delivery after 3 seconds
                // }, 4000);
                break
            case 'single':
                result.innerText = joke.joke
        }
    });
    
    async function getJokes() {
        try {
            let res = await axios.get(url);
            console.log(res)
            let JokeType = res.data.type
            switch(JokeType){
                case 'twopart':
                    let setup = res.data.setup;
                    let delivery = res.data.delivery;
                    return { setup, delivery , JokeType}; // Return both setup and delivery as an object
                case 'single':
                    let joke = res.data.joke;
                    return { joke, JokeType }
                    break
            }
            
            
        } catch (e) {
            console.log("Sorry! Got some error");
            return { setup: "No Joke found", delivery: "" };
        }
    

    };

    This way when you call the API it first checks what kind of joke it is and sends the correct pun to your html. I hope to have helped.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search