0

I’m trying to make a shop command that lists the items that I have added to the shop via another command. I tried to use a for loop to add to the string, but I had no luck with that because the values were undefined For some reason. At this point, I’ve switched to forEach in an attempt to try and make this work, but instead of each value being undefined, it only lists 1 of the 2 items saved in the database.

I am using Enmap to store the shop items.

I filter the shop items using the .filter() function which returns an Enmap (map)

Expected Behavior: The command properly lists all items in the shop (in this case 2 items) and all of their values

Actual Behavior: The embed only shows 1/2 of the items.

const Discord = require('discord.js');
module.exports = {
    id: 'shop',
    aliases: ['buythings', 'linkcoinshop', 'edward'],
    channels: 'guild',
    exec: async (call) => {
        try {

            let filter = await call.client.shopData.filter(find => {
                return find.guildID === call.message.guild.id && find.forSale === true
            });
            if(filter.size === 0) return call.message.channel.send(`There are no items for sale right now.`)
            let embedDesc = '';
            console.log(filter)
                filter.forEach(found => {
                    embedDesc += `**__${found.itemName}__** \nDescription: ${found.itemDesc} \nCost: ${found.itemCost} \nQuantity: ${found.itemQuan} \n\n` 
                })
            const linkCoin = call.client.emojis.get('670675326837194782');
            const shopEmbed = new Discord.RichEmbed()
            .setTitle(`${linkCoin} LinkCoins Shop`)
            .setColor('BLURPLE')
            .setDescription(embedDesc);
            //.setDescription(`🔷: **__Diamond Role__** \nDescription: Gives access to diamond only perks including special giveaways and more! \nCost: 1500${linkCoin} \nQuantity: ♾️ \n\n 💠: **__Diamond + Role__** \nDescription: Access to all perks that Diamond gets you, but with extra abilities such as your own personal voice chats. \n`)
            call.message.channel.send(`Click on the reactions below to purchase.`)
            call.message.channel.send(shopEmbed)
        } catch(error) {
            call.message.channel.send(`Oops! That was an error! The issue has been reported to the adminstration team`);
            console.log(error);
        }
    }
}; 

If anybody has any suggestions of a better way to do this, or just a way to make this work, please let me know. Thanks!

2 Answers 2

1

Always create the minimum amount of code to illustrate your problem. It makes it easier for people to help you, and 8/10 times you will solve it yourself once you extract and isolate your problem.

Sounds like: how do I turn an array of objects into a string containing a list of the object properties?

Looks like you want to do this?

filter.reduce((prev, found) => `${prev}**__${found.itemName}__** \nDescription: ${found.itemDesc} \nCost: ${found.itemCost} \nQuantity: ${found.itemQuan} \n\n`, '')

Test case:

const filter = [
  {
    itemCost: 5,
    itemName: 'snt',
    itemDesc: 'desc',
    itemQuan: 8
  },
  {
    itemCost: 3,
    itemName: 'another',
    itemDesc: 'desc2',
    itemQuan: 10
  }
]
console.log(
  filter.reduce(
    (prev, found) =>
      `${prev}**__${found.itemName}__** \nDescription: ${found.itemDesc} \nCost: ${found.itemCost} \nQuantity: ${found.itemQuan} \n\n`,
    ''
  )
)

Output:

➜ t test.ts
**__snt__** 
Description: desc 
Cost: 5 
Quantity: 8 

**__another__** 
Description: desc2 
Cost: 3 
Quantity: 10 

This should work with Enmap. Per the API Docs:

enmap.reduce(fn, [initialValue]) ⇒ *
Identical to Array.reduce().
Sign up to request clarification or add additional context in comments.

8 Comments

I want it to loop through the items in the returned Enmap and push each value to a string not an array.
The filter works just fine, I just need it put into a string so I can put it in an embed.
That code returns the string you are looking for. I added the test case. You're welcome.
One total string is perfect. I wasn’t sure if reduce would remove the values from the enmap which is not what I want. Thanks for your help! I will set this as the answer for now! I will test it later on today.
Thank you for your help!
|
0

Turns out, there was nothing wrong with the filter or the forEach loop.

Although .reduce() works in my testing, I will continue to use forEach.

My problem was I was setting it all as the same key, which was causing Enmap to overwrite the values, hence only showing 1 of the things I added.

Thanks for all your help!

I will leave Josh's answer as the correct one since his method would work as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.