Reputation: 399
In one of my bot's dialog steps I'am lanching some operations in a setTimeout()
function.
The goal is to clear that TimeOut in an other step in some conditions.
async saveAdults(step) {
if (step.result) {
step.values.adults = step.result;
const convId = step.context.activity.conversation.id;
const format = "dddd DD MMMM YYYY";
// Send partial notification in case of a delay of 5 minutes
const data = {
checkIn: step.values.checkIn,
nights: step.values.nights,
adults: "",
children: ""
};
const timer = await sendPartialNotification(convId, data);
// step.values.timer = timer;
this.notificationProp.set(step.context, timer);
await this.conversationState.saveChanges(step.context);
}
return await step.next();
}
exports.sendPartialNotification = async (convId, data) => {
const interval = 300000;
const timer = setTimeout(() => {
notify(convId, this.id, data, true);
}, interval);
return timer;
};
async notifyClient(step) {
const timer = this.notificationProp.get(step.context);
clearTimeout(timer);
// …
}
Trying to store the TimeOut object in step.values.timer
or in the conversation state throws this error that indicates that it is not possible to parse the Timeout Object ...
TypeError: Converting circular structure to JSON
As solution to this, I was thinking about storing the timer
in Redis ..
Is there any ideas? Thanks.
Upvotes: 0
Views: 136
Reputation: 6418
Use state, props, or equivalent to pass the value from one step to the next. In my example code below, I include a middle step asking if the client would like to cancel. This is purely for displaying output for the solution.
async setTimer(step) {
if (step.result) {
const convId = step.context.activity.conversation.id;
const data = {
value1: someValue1,
value2: someValue2
};
const timer = await sendPartialNotification(convId, data);
this.notificationProp = { step: step.context, timer: timer };
await this.conversationState.saveChanges(step.context);
}
return await step.next();
}
async askClient(step) {
const timer = this.notificationProp.timer;
if (timer._idleTimeout > 0) {
const message = MessageFactory.text(
'Cancel the timer?',
null,
'expectingInput'
);
return await step.prompt('confirmPrompt', message);
}
}
async notifyClient(step) {
const stepResult = step.result;
step.value = { timer: this.notificationProp.timer };
if (stepResult === true) {
console.log('TIMER PRE-CLEAR ', step.value.timer);
const timer = step.value.timer;
await clearTimeout(timer);
console.log('TIMER POST-CLEAR', timer);
step.context.sendActivity('Cancelling timer');
} else {
step.context.sendActivity('Timer not cancelled');
}
return await step.next();
}
Timer not cancelled and executes:
Timer cancelled:
Hope of help!
Upvotes: 1