skip to Main Content

I have this code that executes a function to promise 4 public methods, the public methods have code to return nothing if they don’t meet a certain criteria. If one of the results is empty (undefined), I want it to disregard that result BUT still keep the and execute the other results. Anyone have an idea on how to do this or a workaround for it?

async sendFreeGames(channels) {
        Promise.all([this.createEpicFreeGamesEmbeds(), this.createSteamFreeGamesEmbeds(), this.createEpicFreeButtons(), this.createSteamFreeButtons()]).then(
            (results) => {
                const games = [...results[0], ...results[1]];
                const buttons = [...results[2], ...results[3]];

                if (games.length === 0) return;

                for (const channel of channels) {
                    // @ts-ignore
                    const discordAxios = axios.create({
                        baseURL: 'https://discord.com/api/v10',
                        headers: { Authorization: `Bot ${process.env.DISCORD_TOKEN}` },
                    });
                    discordAxios.post(`/channels/${channel.data.id}/messages`, { embeds: games, components: [{ type: 1, components: buttons }] });
                }
            },
        );
    }
}

2

Answers


  1. To ignore undefined or null values in the result you can just provide a default (ie empty) array before deconstruction

     (results) => {
       const games = [...(results[0] || []), ...(results[1] || [])];
       const buttons = [...(results[2] || []), ...(results[3] || [])];
    
    

    or (if you have more than just a few arrays in the result and want to provide an [] for all of them)

     (results) => {
       results = results.map(x => x || []);
       const games = [...results[0]), ...results[1]];
       const buttons = [...results[2], ...results[3]];
    
    

    But actually, the cleaner approach would be, if your methods would return an empty array instead of undefined

    Furthermore, the way you currently defined your function, ie

    async function foobar() {
      Promise.all([...]).then(...);
    }
    

    anyone calling your function foobar like

    ...
    await foobar();
    ...
    

    will continue way before your Promise.all() resolved.

    Either do

    function foobar() {
       return Promise.all(...).then(...);
    }
    

    or

    async function foobar() {
       let result = await Promise.all(...);
       //process your result array 
    }
    
    Login or Signup to reply.
  2. You seem to be looking for

    async sendFreeGames(channels) {
        const [epicGames, steamGames, epicButtons, steamButtons] = await Promise.all([
            this.createEpicFreeGamesEmbeds(),
            this.createSteamFreeGamesEmbeds(),
            this.createEpicFreeButtons(),
            this.createSteamFreeButtons(),
        ]);
    
        const games = [...epicGames ?? [], ...steamGames ?? []].filter(Boolean);
        const buttons = [...epicButtons, ...steamButtons];
    
        if (games.length === 0) return;
    
        for (const channel of channels) {
            // @ts-ignore
            const discordAxios = axios.create({
                baseURL: 'https://discord.com/api/v10',
                headers: { Authorization: `Bot ${process.env.DISCORD_TOKEN}` },
            });
            discordAxios.post(`/channels/${channel.data.id}/messages`, {
                embeds: games,
                components: [{ type: 1, components: buttons }],
            });
        }
    }
    

    Depending on what exactly those functions return, you may not need the ?? [], or you may not need the .filter(Boolean). You may also need to process your buttons in the same manner.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search