0

I'm using the AWS Javascript SDK and I'm following the tutorial on how to send an SQS message. I'm basically following the AWS tutorial which has an example of the sendMessage as follows:

sqs.sendMessage(params, function(err, data) {
  if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data.MessageId);
  }
});

So the sendMessage function uses a callback function to output whether the operation was successful or not. Instead of printing to the console I want to return a variable, but every value I set is only visible within the callback function, even global variables like window.result are not visible outside the callback function. Is there any way to return values outside the callback?

The only workaround I've found at the moment is to set a data attribute in an HTML element, but I don't think it's really elegant solution.

Vasilis
  • 2,721
  • 7
  • 33
  • 54
  • 2
    Possible duplicate of [How to return value from an asynchronous callback function?](https://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function) – marekful Feb 05 '19 at 16:50
  • 1
    The problem is not visibility but timing. Surely, a global variable is visible globally. What happens in your case is that you you try to access a variable _before_ it is assigned a value, because the callback function executes later in time. – marekful Feb 05 '19 at 16:52
  • @marekful, agreed the question has been asked already, but the accepted answer is from 2011. Fortunately, JS evolved a bit and allow for cleaner solutions today. – Sébastien Stormacq Feb 05 '19 at 16:58
  • @Vasilis, sorry linked the wrong one. Click through its duplicate and check answers there. – marekful Feb 05 '19 at 17:00

1 Answers1

1

I would suggest to use Promises and the new async and await keywords in ES2016. It makes your code so much easier to read.

async function sendMessage(message) {

    return new Promise((resolve, reject) => {

        // TODO be sure SQS client is initialized
        // TODO set your params correctly 
        const params = {
            payload : message
        };

        sqs.sendMessage(params, (err, data) => {
            if (err) {
                console.log("Error when calling SQS");
                console.log(err, err.stack); // an error occurred
                reject(err);
            } else {
                resolve(data);
            }
        });         
    });
}

// calling the above and getting the result is now as simple as :
const result = await sendMessage("Hello World");
Sébastien Stormacq
  • 14,301
  • 5
  • 41
  • 64
  • it could've been just `try { const result = await sqs.sendMessage({..}).promise() } catch (err) throw err }` but OP is trying to implement it in browser and not all browsers support async await syntax. – A.Khan Feb 05 '19 at 17:00