Search code examples
javascriptarrayspromise

Executing non empty promise results while disregarding empty results


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 }] });
                }
            },
        );
    }
}

Solution

  • 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 
    }