-1

So i was trying to create a Discord-Bot which is able to lookup definitions on urbandictionary.. but i am getting an error after trying to fetch the json from their api.

const args = Array.prototype.slice.call(commandArgs);
    if (!args.length) {
    return message.channel.send('You need to supply a search term!');
    }

    const query = querystring.stringify({ term: args.join(' ') });

    const body  = await fetch(`https://api.urbandictionary.com/v0/define${query}`).then(response => response.json());

    console.log(fetch(`https://api.urbandictionary.com/v0/define${query}`).then(response => response.json()));

    if (!body.list.length) {
        return message.channel.send(`No results found for **${args.join(' ')}**.`);
    }

    const [answer] = body.list;

    const embed = new Discord.RichEmbed()
        .setColor('#EFFF00')
        .setTitle(answer.word)
        .setURL(answer.permalink)
        .addField('Definition', trim(answer.definition, 1024))
        .addField('Example', trim(answer.example, 1024))
        .addField('Rating', `${answer.thumbs_up} thumbs up. ${answer.thumbs_down} thumbs down.`);

    message.channel.send(embed);
    }

the error looks like this:

    (node:11948) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
    at Client.client.on (C:\Users\Johannes\Desktop\Vladimir\main.js:176:18)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
(node:11948) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11948) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

the console.log() function in the middle just says: "Promise { pending }"

Zoe
  • 27,060
  • 21
  • 118
  • 148
  • Welcome to StackOverflow. It is not clear why you would call `fetch` a second time within `console.log`. That is quite misleading. – trincot Mar 02 '19 at 16:14
  • yeah sorry ik it was not the best idea ^^ but it should not change anything – Johannes Bauer Mar 02 '19 at 16:15
  • You should provide a [mcve] (one which doesn't depend on data in variables you haven't defined in the example). – Quentin Mar 02 '19 at 16:18
  • Logging the value of `body` would be an obvious first move for debugging this. – Quentin Mar 02 '19 at 16:18
  • ok alright.. the "args"-variable is just the input text which is going to be converted into the querystring.. and i tried to log body but i just got "undefined" – Johannes Bauer Mar 02 '19 at 16:20
  • In your console.log you log the promise immediately after creating it. Therefore the output is what you would expect. If you wanted to output the result you would have to put your console.log inside the then function of the promise. – jBuchholz Mar 02 '19 at 16:22
  • The error `cannot read property 'length' of undefined` indicates that the object you are calling `.length` on does not exist. I would assume that the API you call does not return a list field. A save way to do the desired check would be `if (!body || !body.list || !body.list.length)` – jBuchholz Mar 02 '19 at 16:25
  • try to add a catch to the fetch statement. I think the api is returning an error – Soulimane Mammar Mar 02 '19 at 16:27
  • @Scorpioo590 but if i add these exceptions to my if clause it will always tellme that there are no results cause body would be still undefined.. – Johannes Bauer Mar 02 '19 at 16:29

1 Answers1

-1

If we never encountered hard problems coding we probably aren’t trying hard enough. And instead of giving up you asked for help. Being smart enough to do all that puts you in a good spot.

In your code you have an await command. For this to work async needs to be placed before the beginning of the outer function. Keep in mind that await only works with promises. Also note that you have fetch once next to body and then again in the console statement. This would cause two requests when we only need one. Hope the updated snippet below helps you out.

getUrbanDictionaryDefs = async function() {
  const args = Array.prototype.slice.call(commandArgs);
  if (!args.length) {
    return message.channel.send("You need to supply a search term!");
  }

  const query = querystring.stringify({ term: args.join(" ") });

  let body;

  try {
    body = await fetch(`https://api.urbandictionary.com/v0/define${query}`);
  } catch (err) {
    console.log(err);
    return;
  }

  body = body.json();

  console.log(body);

  if (!body.list.length) {
    return message.channel.send(`No results found for **${args.join(" ")}**.`);
  }

  const [answer] = body.list;

  const embed = new Discord.RichEmbed()
    .setColor("#EFFF00")
    .setTitle(answer.word)
    .setURL(answer.permalink)
    .addField("Definition", trim(answer.definition, 1024))
    .addField("Example", trim(answer.example, 1024))
    .addField(
      "Rating",
      `${answer.thumbs_up} thumbs up. ${answer.thumbs_down} thumbs down.`
    );

  message.channel.send(embed);
};
amcnutt
  • 59
  • 2