Reputation: 63
I need to make two requests for a simply intent. The user response some questions and I do these two requests to same API with a diferent parameter.
I tried several things and on the last try I use a Promisse to make these two requests and return data.
These function execute my put and get the return:
async function getData(url, config, body) {
let result = await axios.put(url, body, config);
let returnValues = [];
if(result.data){
if (Array.isArray(result.data)) {
result.data.forEach(item => {
returnValues.push(item.message);
});
} else {
returnValues.push(result.data.message);
}
}
return returnValues;
}
These function is my handler
function getDocumentHandler(agent){
const url = 'https://myUrl';
const authorization = 'myBasicAuth';
const dateformat = 'YYYYMMDD';
const config = {
headers: {
'Authorization': 'Basic ' + authorization ,
'Content-Type': 'application/json'
}
};
const value = agent.parameters.value1;
const flag = agent.parameters.flag;
var xmlBody = '<value>' + value + '</value>';
return new Promise((resolve, reject) => {
getData(url, config, xmlBody).then(
(res) => {
if(res != null && res.length > 0){
console.log('Values without flag: ', res.length);
res.forEach(item => {
console.log('Item: ' , item);
agent.add(item);
});
}
}
);
if(flag){
xmlBody += ' <flag>true</flag>';
getData(url, config, xmlBody).then(
(res) => {
if(res != null && res.length > 0){
console.log('Values with flag: ', res.length);
res.forEach(item => {
console.log('Item: ' , item);
agent.add(item);
});
}
}
);
}
resolve();
});
}
Important information:
Anyone can help me?
Thanks
Upvotes: 0
Views: 440
Reputation: 413
When an intent handler returns a promise, your WebhookClient
will create a webhook response based on the response that you added using the add()
function, and then send it to your agent once the promise is fulfilled.
In your case, the promise that is returned by your intent handler is being fulfilled even if your getData()
promise handlers containing the agent.add()are not yet fulfilled, as your getData()
functions are not awaited before calling the resolved()
function to fulfill the promise return by your intent handler. Therefore, your WebhookClient will be unable to create a response to be sent back to your agent as there will be no responses defined.
There are two ways to fix this problem. The first one is by calling the resolved()
function of the returned promise of your intent handler inside of your getData()
promise handlers.
return new Promise(async (resolve, reject) => {
await getData(url, config, xmlBody).then(
(res) => {
if(res != null && res.length > 0){
console.log('Values without flag: ', res.length);
res.forEach(item => {
console.log('Item: ' , item);
agent.add(item);
});
}
}
);
if(flag){
xmlBody += ' <flag>true</flag>';
await getData(url, config, xmlBody).then(
(res) => {
if(res != null && res.length > 0){
console.log('Values with flag: ', res.length);
res.forEach(item => {
console.log('Item: ' , item);
agent.add(item);
});
}
resolve();
}
);
}
}
And the second one is by adding the async
keyword in your promise handler and the await
keyword when calling your getData function inside your promise handler.
return new Promise(async (resolve, reject) => {
await getData(url, config, xmlBody).then(
(res) => {
if(res != null && res.length > 0){
console.log('Values without flag: ', res.length);
res.forEach(item => {
console.log('Item: ' , item);
agent.add(item);
});
}
}
);
if(flag){
xmlBody += ' <flag>true</flag>';
await getData(url, config, xmlBody).then(
(res) => {
if(res != null && res.length > 0){
console.log('Values with flag: ', res.length);
res.forEach(item => {
console.log('Item: ' , item);
agent.add(item);
});
}
}
);
}
resolve();
}
When you await
a promise, the function is paused in a non-blocking way until the promise is fulfilled.
However, if your fulfillment code is deployed using Dialogflow’s inline editor, note that the inline editor does not support async functions.
Upvotes: 1