1

So one of my files has a function that I need two of my other files to access. I am exporting this function with module.exports = {}. For some reason, one of my files is able to call this function, while I get a commands.commandRouter is not a function error when trying to call it from the other file. Here's basically what I've got going on:

commands.js

function commandRouter(commandName, commandType) {
    if (commandType == 'sound') {
        console.log(`${commandName} is a sound command, executing sound function`)
        playAudio.playAudio(commandName.substring(1));
    }
}

module.exports = {commandRouter}

main.js

const commands = require('./modules/commands.js');
const secondary = require('./modules/secondary.js');


client.on('message', (channel, tags, message, self) => {
    if(message.charAt(0) == '!'){
        console.log('Trigger character identified');
        if(commands.commandList.hasOwnProperty(message.toLowerCase())) {
            console.log('Valid command identified')
            if (commands.commandList[`${message}`] == 'random' ) {
                console.log('Random-type command identified')
                secondary.randomSelectPropery(message.toLowerCase().substring(1));
            }
            else
            {
                console.log('Regular command identified')
                commands.commandRouter(message, commands.commandList[`${message}`]);
            }
            
        }
    }
}

commands.commandRouter(paramA, paramB); works just fine in this instance

secondary.js

const commands = require('./commands.js');

var randomSelectPropery = function (commandObject) {
    randomObject = eval(commandObject);
    var keys = Object.keys(randomObject);
    console.log(randomObject)
    console.log(`This object has ${keys.length} commands to choose from`);
    var newCommandName = Object.getOwnPropertyNames(randomObject)[keys.length * Math.random() << 0];
    console.log(newCommandName)
    var newCommandType = randomObject[`${newCommandName}`]
    console.log(newCommandType);
    commands.commandRouter(newCommandName, newCommandType);
};

const perfect = {
    "!perfectqube": "sound",
    "!perfectsf2": "sound",
};

module.exports = { perfect, randomSelectPropery }

Here, commands.commandRouter(paramA, paramB); give the commands.commandRouter is not a function error.

File structure is as follows:

.\folder\main.js
.\folder\modules\commands.js
.\folder\modules\secondary.js
  • Did you check that `commands` is imported properly in the second file? – thanhdx Nov 24 '20 at 02:51
  • so, `secondary.js` is in the same folder as `commands.js`? and `jsWithFunction.js` is actually `commands.js`? and what is `commands.commandList` - it's not in the same file where `commands.commandRouter` is defined by the look of it ... are you sure you're not dealing with completely different files? – Bravo Nov 24 '20 at 02:52
  • Apologies, I forgot to mention my file structure. `commands.js` and `secondary.js` are in the same folder, `./modules`. jsWithFunction.js was just a stand-in, editing question to be more clear. – Chump Fighter Nov 24 '20 at 02:54
  • You say the error is related to `jsWithFunction.exportedFunction`, but you don't show where that comes from or where it's supposed to be imported from or where the error occurs. As a consequence, we can't really figure out how to follow the chain of imports to see where something is going wrong. And, rather than saying "other file", please be specific about exactly which file the error occurs in and show the relevant imports and attempt to call it in that file. – jfriend00 Nov 24 '20 at 02:56
  • Thx for the clarifying edits. Did you try `console.log(commands)` in `secondary.js` to see what it is. – jfriend00 Nov 24 '20 at 03:04
  • Okay, `console.log(commands)` returns `commandRouter: [Function: commandRouter]`, as well as an object named `commandList` that `commands.js` is also exporting – Chump Fighter Nov 24 '20 at 03:14
  • 1
    Figured it out, seems to have been a scope issue. Redefined the problematic function with `global.commandRouter = function commandRouter(commandName, commandType)` and that seems to have resolved the issue, though there may be a more elegant solution I am unaware of. – Chump Fighter Nov 24 '20 at 04:58
  • @ChumpFighter - Making something a global that should be an export from a module is a hack and not a good one. That is not the way to solve problems like htis. – jfriend00 Nov 24 '20 at 07:19
  • I'm guessing there must be more to` secondary.js` than what you are showing us where somehow either the timing of when commands is getting initialized is different or something else is overriding it or it's in a different scope than you show. Can you show us that entire file? – jfriend00 Nov 24 '20 at 07:31
  • All of `secondary.js` is there. I've found that if I put `console.log(commands)` in the `randomSelectPropery ` function, it returns the error `(node:17428) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency` – Chump Fighter Nov 24 '20 at 21:35
  • @jfriend00 Just passing by, I am curious to your comment you made about the `...hack and not a good one.`. Can you expand on that please? I'd like to understand to what you mean by that. – Eduards Nov 24 '20 at 21:47
  • 1
    @LV98 - Nodejs is a modular development environment. To keep the community from turning into a big mess of conflicting global symbols in the thousands of libraries available to run on nodejs, you don't make your public methods be globals. Instead you export them from your module and anyone else who wants to use them can import them and nothing is global and nothing will conflict. – jfriend00 Nov 24 '20 at 22:08
  • 1
    @LV98 - Another reference on the topic [Why are globals considered bad practice in nodejs](https://stackoverflow.com/questions/18635136/why-are-global-variables-considered-bad-practice-node-js). – jfriend00 Nov 24 '20 at 22:10

0 Answers0