简体   繁体   中英

Item doesn't want to be pushed into an array

I am developing a discord bot that allows you to mine for resources, but I can't get the code to work. It's logging the actual items, but it just doesn't add the items to the array, which is why I can't map it into a string.

Code:

module.exports.addItem = async (client, user, item, amount, interaction) => {
    if(!client instanceof Client) throw new Error("Client is not an instance of Discord.js Client");
    if(!user instanceof User) throw new Error("User is not an instance of Discord.js User");
    if(!item) throw new Error("Item is not defined");
    if(!amount) throw new Error("Amount is not defined");
    if(typeof amount !== "number") throw new Error("Amount is not a number");
    if(!interaction) throw new Error("Interaction is not defined");
    if(!interaction instanceof Interaction) throw new Error("Interaction is not an instance of Discord.js Interaction");

    const userFound = await client.database.user.findOne({ userID: user.id });
    if(!userFound) return interaction.followUp({ content: `You haven't started your journey yet!` });

    const itemFound = userFound.inventory.find(i => i.name === item.name);
        if(!itemFound) {
            await client.database.user.findOneAndUpdate(
                {
                    userID: user.id,
                }, {
                    userID: user.id,
                    $push: {
                        inventory: {
                            name: item.name,
                            amount,
                            category: item.category
                        }
                    }
                } , {
                    upsert: true,
            });
        } else {
            await client.database.user.findOneAndUpdate(
                {
                    userID: user.id,
                }, {
                    userID: user.id,
                    $pull: {
                        inventory: {
                            name: item.name
                        }
                    } 
                } , {
                    upsert: true,
            });
                
            await client.database.user.findOneAndUpdate(
                {
                    userID: user.id,
                }, {
                    userID: user.id,
                    $push: {
                       inventory: {
                            name: item.name,
                            amount: item.amount + amount,
                            category: item.category
                        }
                    }
                } , {
            upsert: true,
        });
    }
    return { name: item.name, amount, category: item.category };
}

module.exports.dropItem = async (client, user, category, interaction) => {
    if(!client instanceof Client) throw new Error("Client is not an instance of Discord.js Client");
    if(!user instanceof User) throw new Error("User is not an instance of Discord.js User");
    if(!category) throw new Error("Category is not defined");
    if(typeof category !== "string") throw new Error("Category is not a string");

    let droppedItems = [];
    
    for (const item of client.items) {
        for(let i = 0; i < client.items.length; i++) {
            if(!client.items[i].category === category) return;
        }

        const dropAmount = Math.floor((Math.random() * 3) + 1);
        const dropChance = Math.floor(Math.random() * 100);
        if(dropChance > item.dropChance) return;

        const itemDropped = await this.addItem(client, user, item, dropAmount, interaction)
        console.log(itemDropped); // This logs the item correctly

        droppedItems.push(itemDropped);
    }

    return droppedItems; // This always returns "undefined"
}

Expected result: An array with objects, each object containing a name, amount and category value;

Actual result: Console-logging the array returns "undefined"

I have tried awaiting the push, making the array a constant and more small things like that. Could it be because the array isn't in the loop?

The problem is probably that you have several return statements in your dropItem function that are returning undefined .

For example if(dropChance > item.dropChance) return;

A simple function to illustrate this is:

const doSomething = () => {
    const arr = [1, 2, 3]
    for (const num of arr) {
        if (num !== 10) return
  }
    return 'done'
}

You are saying that you would expect the above function to return "done", but it will actually return undefined .

I think maybe you want to use break instead of return , but not sure exactly what behaviour you are expecting. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break

Since you are awaiting a call within the for loop, you will need to await the entire loop as well. You can do this with await Promise.all(<<ARRAY OF PROMISES>>) .

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

So you'd do something like

let droppedItems = [];
await Promise.all(client.items.map(async (item) => {
        for(let i = 0; i < client.items.length; i++) {
            if(!client.items[i].category === category) return;
        }

        const dropAmount = Math.floor((Math.random() * 3) + 1);
        const dropChance = Math.floor(Math.random() * 100);
        if(dropChance > item.dropChance) return;

        const itemDropped = await this.addItem(client, user, item, dropAmount, interaction)
        console.log(itemDropped); // This logs the item correctly

        droppedItems.push(itemDropped);
    }));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM