javascriptnext.js

Code doesn't wait for the response before continuing in async await function


I have this code in one file:

export async function POST(req) {
...
const SMSSent = await sendSMS(phoneToSendSMS, bodyToSend)
    
        console.log('res from sendSMS', SMSSent);
    if (SMSSent?.error) {
                await prisma.token.delete({
                    where: {
                        id: res.tokenId,
                    },
                });
        console.log('-------------error sending SMS Token deleted---------------------');
        return new NextResponse(JSON.stringify({ error: "Une erreur s'est produite" }), { status: 422 });
}
    //finally return a response 200
    else return new NextResponse(JSON.stringify({ message: "Un SMS a été envoyé sur votre téléphone" }), { status: 200 });
}

And it call the sendSMS

export default async function sendSMS(phoneNumber, body) {
    const options = {
        method: "POST",
        headers: { accept: "application/json", "content-type": "application/json", "api-key": process.env.BREVO_API_KEY },
        body: JSON.stringify({
            sender: "maillart",
            recipient: phoneNumber,
            content: body,
            type: "transactional",
            unicodeEnabled: false,
            tag: "accountValidation",
        }),
    };
    fetch("https://api.brevo.com/v3/transactionalSMS/sms", options)
            .then((response) => response.json())
            .then((data) => {
                console.log("-------res is coming--------", data);
                if (data.message) {
                    console.log("-------------------------SMS not sent1-------------------------------", data.message);
                    return data.message;
                }
                console.log("-------------------------SMS sent-------------------------------");
                return { error: "Une erreur s'est produite" }
            })
            .catch((err) => {
                console.log("-------------------------SMS not sent2-------------------------------");
                console.log("erreur ::", err);
                return { error: "Une erreur s'est produite" };
            });
}

but this is not working as expected because I always get:

res from sendSMS undefined

before any other logs and response

For example:

res from sendSMS undefined
-------res is coming-------- { code: 'invalid_parameter', message: 'Invalid telephone number' }
-------------------------SMS not sent1------------------------------- Invalid telephone number

I tried many different way to write this code and debug this but I didn't succeed.

Any help would be highly appreciated.


Solution

  • Putting something in an async function and awaiting on that function does not automatically make them synchronous.

    To fix this, you need to also put await on the fetch call:

    const sendSMS = async () => {
      const res = await fetch();
      const data = await res.json();
      return data;
    };
    
    const data = await sendSMS();
    

    Or just return the promise from fetch (note sendSMS does not have to be an async funtion in this case):

    const sendSMS = () => {
      
      return fetch("https://api.brevo.com/v3/transactionalSMS/sms", options)
        .then((response) => response.json())
        .catch((err) => {});
    };
    
    const data = await sendSMS();