Node.js JsonParser custom function “cannot read property of undefined”

Tags: , , , ,



I am trying to make a JSON function that will be able to return parsed data from JSON files for multiple other functions without needing to rewrite the same code over and over. Here is the function I have, along with a variable:

var fs = require('fs');
function jsonParser(jsonFile) {
    fs.readFile(jsonFile,
        function (err, data) {
            var jsonData = data;
            var jsonParsed = JSON.parse(jsonData);
            return jsonParsed;
        })
};

When I insert a console.log into this function for testing, it returns the data from jsonParsed without any issue. Here is one example of how+where this function will be used:

msg.channel.send(jsonParser('package.json').version);

And here is the JSON file this is loading from:

{
  "name": "discord-bot",
  "version": "0.4.0",
  "description": "Mírre from The Autorise Domain recreated as a Discord bot",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  }
}

I’ve tried multiple ways to try to get the “version” data, but it keeps returning the same “cannot read property of ‘version’ of undefined” message every time. I would like to be able to push the object data through msg.channel.send(), but that isn’t happening — as if the program has already wiped the object out of memory by the time it reaches the send function.

Any help would be greatly appreciated!

EDIT: The function is being called within a Discord.Client() message function. After defining the bot as const bot = new Discord.Client(), the command that jsonParser is used in is called from a large bot.on('message'... function. From here, there is a switch-case of multiple commands someone can give the bot, with one of them being used to find the bot’s version; this is where jsonParser is being called from.

Answer

As I commented, changing to fs.promises works without problem:

const fs = require('fs');
const path = require('path');

async function jsonParser(jsonFile) {
  const data = await fs.promises.readFile(path.resolve(__dirname, jsonFile));

  var jsonData = data.toString('utf-8');
  var jsonParsed = JSON.parse(jsonData);
  return jsonParsed;
};

(async function (jsonFile) {
  const data = await jsonParser(jsonFile);
  console.log(data.version);
})('./test.json').catch(e => {
  console.log(e);
});

Because this code is being used for a Discord bot, make sure that the .on function for the client is using an async() like so:

const bot = new Discord.Client();
...
bot.on('message', async(msg) => {...}


Source: stackoverflow