Reputation: 23
I am currently working on an Alexa Skill to collect data from an SAP system. Because of a callback in my function to collect the data, Alexa speaks, before the speakOutput variable gets updated.
const LagerhueteIntent = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
Alexa.getIntentName(handlerInput.requestEnvelope) === 'LagerhueteIntent';
},
handle(handlerInput) {
let speakOutput;
console.log("test");
findWarehouseKeepers(function(warehouseKeeper) {
console.log(warehouseKeeper);
speakOutput = "Die Lagerhüter sind die Produkte mit den Ids" + warehouseKeeper;
console.log(speakOutput);
});
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
With my function:
function findWarehouseKeepers(callback) {
var args = getArgs();
console.log(args);
var Client = require('node-rest-client').Client;
var client = new Client();
client.get("http://XXXXXXXX$format=json", args, function(data, response) {
let validValuesList = new List([]);
data.d.results.forEach(function(data) {
validValuesList.add(data.ProductId);
});
console.log(validValuesList);
let validValuesAsArray = validValuesList.toArray();
console.log(validValuesAsArray);
callback(validValuesAsArray);
});
}
How can I get my function synchronized, so the speakOutput variable gets updated before the next code gets executed? Thanks in advance.
Upvotes: 2
Views: 49
Reputation: 816840
As per documentation, handle
can return a promise, which will allow you to build the response once you received the data.
Ideally you would change findWarehouseKeepers
to return a promise, but here is an example with minimal changes to your code:
handle(handlerInput) {
return new Promise(resolve => {
findWarehouseKeepers(warehouseKeeper => {
const speakOutput = "Die Lagerhüter sind die Produkte mit den Ids" + warehouseKeeper;
resolve(
handlerInput.responseBuilder
.speak(speakOutput)
.getResponse()
);
});
});
}
Of course you would also want to think about what to do if the request fails, i.e. you want to reject the promise.
If you change findWarehouseKeepers
to return a promise then you could probably write declare handle
as async
(I don't know in which environment this code runs) and write the code in a way that looks synchronous:
async handle(handlerInput) {
const warehouseKeeper = await findWarehouseKeepers();
return handlerInput.responseBuilder
.speak("Die Lagerhüter sind die Produkte mit den Ids" + warehouseKeeper)
.getResponse()
}
Upvotes: 2