IotaMoon
IotaMoon

Reputation: 1

TypeError: Cannot read property 'NaN' of undefined

I'm getting issues with this code. It gives me the following error:

TypeError: Cannot read property 'NaN' of undefined

dotenv.config();
  
client.on("ready", () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on("message", async (msg) => {
 
  const tokens = msg.content.split(" ");

  
  if (tokens[0] === "!gif") {
   
    const keywords = tokens.slice(1, tokens.length).join(" ");
    
    const url = `https://api.tenor.com/v1/search?q=${keywords}&key=${process.env.EK3M4TY0S70Y}&limit=10`;
    
    const response = await fetch(url);
    
    const result = await response.json();
    
    const index = Math.floor(Math.random() * result.length);
    
    msg.channel.send(result.results[index].url);
  }
});

Upvotes: 0

Views: 1340

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42258

Property NaN

The NaN in your code is the variable index. If result.length is undefined then Math.floor(Math.random() * result.length) will be NaN.

When you try to get an item from the array you are using result.results[index] which implies that result is an object with a results property which is an array. So the result itself is not an array and accessing result.length doesn't make sense. You would want result.results.length`.

Of undefined

The error "Cannot read property 'NaN' of undefined" comes from result.results[index]. so if index is the NaN property then result.results is the undefined value. The Tenor API should return an object with a results property, so this is likely due to a malformed request. If you have an invalid key for example, your response will be an object with a property error and no results. You could also have an invalid q, so you'll want to escape it with encodeURIComponent.

I don't have enough information to know why the request is failing for you, but we can check that we have an array and console.log the result otherwise so that you can inspect it (or throw an Error). When you improve the code a bit more you'll want to introduce try/catch blocks.

const testFunc = async (msgContent, apiKey = "") => {
  const tokens = msgContent.split(" ");

  if (tokens[0] === "!gif") {
    const keywords = encodeURIComponent(
      tokens.slice(1, tokens.length).join(" ")
    );

    // seems to work with no key at all
    const url = `https://api.tenor.com/v1/search?q=${keywords}&key=${apiKey}&limit=10`;

    const response = await fetch(url);

    const result = await response.json();
    
    if ("results" in result) {
      const images = result.results;

      const index = Math.floor(Math.random() * images.length);

      return images[index].url;
    } else {
      console.log("Invalid Response", result);
    }
  }
};

testFunc("!gif cat", "").then(console.log);

Upvotes: 2

Related Questions