Search code examples
node.jsjsondiscordpokeapi

Displaying an JS Object in JSON from PokeAPI for DiscordBot


I am trying to work on my discord bot and get information from the PokeApi, specifically the movelists of pokemon. I have the following code, but Im struggling figuring out how to get the movelist for each pokemon.

client.on('message',(async message =>{
    const args = message.content.toLowerCase().slice(poke.prefix.length).split(/ +/);
    if(!message.content.startsWith(poke.prefix))return;
    if(args[0] === "api"){
        const fetch = require ('node-fetch');
        fetch('https://pokeapi.co/api/v2/pokemon/25')
        .then(res => res.json())
        .then(data => message.channel.send(data.name.moves.move.name))
        .catch(err => message.reply('that spell does not exist!'));}}))

Now I know Im specifying a specific pokemon here (number 25), which is fine because I can change that later but this is the part that seems to be setting me back:

.then(data => message.channel.send(data.name.moves.move.name))

Also is there a clean way to create an embed with the data. Do I have to make a variable that has information or could I use "res"?

Any help or guidance with this is greatly appreciated! Thank you!


Solution

  • The way you're slicing data off the API is incorrect. There is no data.name.moves.move.name in the response, so reading it will cause the following error:

    TypeError: Cannot read property 'move' of undefined
    

    Instead, the response looks more like the following (with only the relevant bits shown):

    {
      "name": "pikachu",
      "moves": [
        {
          "move": {
            "name": "mega-punch",
            "url": "https://pokeapi.co/api/v2/move/5/"
          }
        },
        {
          "move": {
            "name": "pay-day",
            "url": "https://pokeapi.co/api/v2/move/6/"
          }
        },
        ...
      ]
    }
    

    So, depending on what you want to do with the moves, you would need to massage the array of moves into the format you want. For example, to give them back a comma-separated list of moves, try the following:

    fetch('https://pokeapi.co/api/v2/pokemon/25')
      .then(res => res.json())
      .then(data => {
        // Convert to `string[]` of move names
        const moves = data.moves.map(moveData => moveData.move.name);
        // Send message with a comma-separated list of move names
        message.channel.send(moves.join(','));
      });
    

    As far as creating embeds, these are fairly easy to build up following the Embed Structure documentation:

    fetch('https://pokeapi.co/api/v2/pokemon/25')
      .then(res => res.json())
      .then(data => {
        // Convert to `string[]` of move names
        const moves = data.moves.map(moveData => moveData.move.name);
        // Send message with embed containing formatted data
        message.channel.send({
          embeds: [{
            // Set embed title to 'pikachu'
            title: data.name,
            // Add embed field called 'moves', with comma-separated list of move names
            fields: [{
              name: 'Moves',
              value: moves.join(','),
            }],
          }],
        });
      });