Search code examples
javascriptnode.jsbotsdiscord

How would I assign a Javascript variable to another Javascript variable? (a little confusing, i know)


So, I have had a problem recently!

I was trying to assign a value to a variables value (a little confusing, i know). I was trying to make a library system for my Discord bot, which uses JavaScript (Node.js)!

So, here's a part of the code that I was struggling with:

    flist.forEach(item1 => {
        liblist.forEach(item => {
            eval(item1 = require(item));
        });
    });

OK, so basically item1 has to be replaced with a library file's name (if a file is named cmdh, I use that as a variable name to assign require(item) to it)

Edit: the item1 is the file name, by the way.

Edit 2: Here's a part of the file util.js:

const Discord = require("discord.js");
const fs = require("fs");
function genEmbed(title, desc, col) {
    return new Discord.MessageEmbed().setTitle(title).setDescription(desc).setColor(col);
};
function log(inp) {
    console.log(`[UTIL] ${inp}`);
};

function loadDef() {
    log("Loading libraries...");
    dirlist = [];
    liblist = [];
    flist = [];
    fs.readdir("./libraries", (err, dirs) => {
        if(err) console.error(err);
        dirs.forEach(dir => {
            dirlist.push("./libraries/" + dir); 
        });
        dirlist.forEach(dir => {
            fs.readdir(dir, (err, files) => {
                if(err) console.error(err);
                files.forEach(file => {
                    if(file.includes(".")) {
                        liblist.push(require(dir + "/" + file));
                        filename = file.split(".")[0];
                        flist.push(filename);
                    } else {
                        log(`${file} is a directory, ignoring...`)
                    };
                });
            });
        });
    });
    flist.forEach(item1 => {
        liblist.forEach(item => {
            eval(item1 = require(item));
        });
    });
    log("Libraries loaded!");
};

module.exports = {
    genEmbed,
    loadDef
};

Solution

  • If you are trying to assign a new value for each element in an array and return a new array with the updated values, you should use map instead of forEach.

    If you want to return an array with the required libraries from liblist and store the result in flist, your code should look as follows:

        flist = liblist.map(item => require(item));
    

    Essentially, map takes each value from an array, applies a function to it (in your case, require), and then returns a new array with the results of the function.

    It should be noted that you also need to replace fs.readdir with fs.readdirSync, otherwise liblist will be empty when the code is called.


    After our discussion on the chat I understood that you want to set the variables as globals in your main file. However, this is a bit hackish. To do that you need to modify the global object.

    Note: I would advise you to statically require via const libraryName = require('./libraries/fileName.js') instead, as this way of dynamically defining libraries has no advantage in this case and only makes the code more complicated. Dynamically requiring libraries only makes sense when you, for example, add listeners via your libraries, but then you do not need to store them as globals.

    Your full code for the utils file should now look as follows:

    const Discord = require("discord.js");
    const fs = require("fs");
    function genEmbed(title, desc, col) {
        return new Discord.MessageEmbed().setTitle(title).setDescription(desc).setColor(col);
    };
    function log(inp) {
        console.log(`[UTIL] ${inp}`);
    };
    
    function loadDef() {
        log("Loading libraries...");
        libraries = {};
        const dirlist = fs.readdirSync("./libraries").map(dir => "./libraries/" + dir)
        dirlist.forEach(dir => {
            const files = fs.readdirSync(dir)
            files.forEach(file => {
                if(file.includes(".")) {
                    filename = file.split(".")[0];
                    libraries[filename] = require(dir + "/" + file);
                } else {
                    log(`${file} is a directory, ignoring...`)
                };
            });
        });
        log("Libraries loaded!");
        return libraries;
    };
    
    module.exports = {
        genEmbed,
        loadDef
    };
    

    Now you still need to modify the code in your main file, as follows:

    const libraries = loadDef()
    global = Object.assign(global, libraries) // assign libraries to global variables