-2

I want to create a channel with different courses. Each course will be stored in an array and will have 1 message containing the course name. We add a thread to this message. And when all threads are created, I want to create a table of contents in an embed linking to each thread in 1 click (thanks to the id of the corresponding thread)

Why does the code for sending the table of contents message run before the threads are created? How can I get the table of contents to be created directly at the very end?

client.on("messageCreate", message => {
    arrayCourses = [["Course 1","https://example.xyz"],["Course 2","https://example2.xyz"]]
    desc = "";
    if(message.content === "$a go"){
        arrayCourses.forEach( async element => {
            var randomColor = Math.floor(Math.random()*16777215).toString(16);

            let y = await message.channel.send({embeds:[ //sends a message on which we will create a thread
                {
                    color: parseInt("0x" + randomColor),
                    title: element[0]
                }
            ]});

            y.startThread({ //create a thread on the message just send
                name: element[0],
                autoArchiveDuration: 60,
                type: 'GUILD_PUBLIC_THREAD'
            }).then( result => {
                desc += result.id + "\n" //add the id of the created thread to a string.
            })
        });
            
        //Send a message with the table of contents
        message.channel.send({embeds:[{
            color: 0x1515,
            title: "Table des matières・JLPT N5",
            description: desc,
            footer: {text: "Pour rechercher un cours : a!search <recherche>", icon_url: "https://images.emojiterra.com/twitter/512px/1f50d.png"}
        }]});
        
    }
})
Konrad
  • 21,590
  • 4
  • 28
  • 64
Azurda
  • 1
  • 2
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – David Sep 14 '22 at 17:22
  • 1
    Because creating threads is an asynchronous process, each need their own time to complete. While the threads are being created the procedure continues, where it will execute your embed send. I recommend wrapping your thread creating code in a function then awaiting said function before sending an embed – Elitezen Sep 14 '22 at 17:26
  • I think I don't see how to do this... Sorry, can you update my code to show me how to do this ? @Elitezen – Azurda Sep 14 '22 at 17:40

1 Answers1

0

You are creating new async functions, but you never await for them

Changing forEach to map and using Promise.all will help

client.on("messageCreate", message => {
    arrayCourses = [["Course 1","https://example.xyz"],["Course 2","https://example2.xyz"]]
    desc = "";
    if(message.content === "$a go"){
        // you have to await for the promises you created
        await Promise.all([arrayCourses.map( async element => {
            var randomColor = Math.floor(Math.random()*16777215).toString(16);

            let y = await message.channel.send({embeds:[ //sends a message on which we will create a thread
                {
                    color: parseInt("0x" + randomColor),
                    title: element[0]
                }
            ]});

            // await for this as well
            const result = await y.startThread({
                name: element[0],
                autoArchiveDuration: 60,
                type: 'GUILD_PUBLIC_THREAD'
            })
            desc += result.id + "\n"
        })]);
            
        //Send a message with the table of contents
        message.channel.send({embeds:[{
            color: 0x1515,
            title: "Table des matières・JLPT N5",
            description: desc,
            footer: {text: "Pour rechercher un cours : a!search <recherche>", icon_url: "https://images.emojiterra.com/twitter/512px/1f50d.png"}
        }]});
        
    }
})
Konrad
  • 21,590
  • 4
  • 28
  • 64