Home > Back-end >  Function returning undefined with nested readFile function, discord.js
Function returning undefined with nested readFile function, discord.js

Time:11-25

I wrote a function that should return a date from a JSON file based on the user's id but I'm getting undefined. When I place the readFile function inside the messageCreate event listener, it works. It just doesn't work when the code is placed in a function.

Here's the js

function GetDate(userid) {
  fs.readFile("users.json", "utf-8", (err, jsonString) => {
    if(err) {
      return err;
    } else {
      try {
        const obj = JSON.parse(jsonString);
        let date = "";
        for (i=0; i < obj.users.length; i  ) {
          if(obj.users[i].id === userid){
            date = obj.users[i].date;
          }
        }
        return date;
      }
      catch {
        return "Error parsing JSON!"   err;
      }
    }
  })
}

Here's the messageCreate event listener that calls the function.

client.on("messageCreate", message => {
  if(message.content === "test") {
    const date = GetDate(message.author.id);
    console.log(date);
  }
})

Here's the JSON file

{
  "users": [
    {
      "id": "1010101010",
      "date": 1671876850
    },
    {
      "id": "2020202020",
      "date": 1671451250
    }
  ]
}

CodePudding user response:

You don't return anything from GetDate. You return inside a callback function only.

If you want to use callbacks, you will need to pass a callback function to getDate and call that function once you get the results (or an error).

Check out the code below. I've also simplified that for loop a bit.

const fs = require('fs');
// ...
function getDate(userid, callback) {
  fs.readFile('./src/users.json', 'utf-8', (err, jsonString) => {
    if (err) return callback(err);

    try {
      const obj = JSON.parse(jsonString);
      for (let user of obj.users) {
        if (user.id === userid) {
          return callback(null, user.date);
        }
      }
    } catch (err) {
      return callback('Error parsing JSON!'   err);
    }
  });
}

client.on('messageCreate', (message) => {
  if (message.content === 'test') {
    // date is only available inside the callback function
    getDate(message.author.id, (date) => {
      console.log(date);
    });
  }
});

You could also use promises though. This makes your code more readable:

const { readFile } = require('fs/promises');
// ...
async function getDate(userid) {
  try {
    const data = await readFile('./src/users.json', 'utf-8');
    const obj = JSON.parse(data);
    for (let user of obj.users) {
      if (user.id === userid) {
        return user.date;
      }
    }
  } catch (err) {
    throw err;
  }
}

client.on('messageCreate', async (message) => {
  if (message.content === 'test') {
    const date = await getDate(message.author.id);
    console.log({ date });
  }
});
  • Related