I'm trying to implement a RiveScript-based chatbot in Angular. The chatbot's working great - I always get the right answer in the console. Displaying the user's input is working great too. However, I always get stuck at one point: Displaying the chatbot's answer in the chat UI because of the following error:
ERROR Error: Uncaught (in promise): TypeError: this is undefined
I have really tried so many things, but I can't find the problem. From my point of view it is also a bit confusing because I can get the right chatbot message in the console. I would be happy if someone could help me to solve this problem!
Here is my source code with comments and the console log as a screenshot. So you can see that the code works.
converse(msg: string) {
const userMessage = new Message(msg, 'user'); //gettng user message
this.update(userMessage);
var bot = new RiveScript({utf8: true}); // initializing bot
bot.loadFile('/assets/brain/test.rive').then(loading_done); // loading bot brain
function loading_done() {
console.log("Chatbot initialized!");
bot.sortReplies(); //sorting replies
let username = "user";
return bot.reply(username, msg).then(answer => { //getting chatbot answer
console.log("User: " + msg);
console.log("Chatbot: " + answer);
const result = answer;
const botMessage = new Message(result, 'bot');
this.update(botMessage);
});
}
}
Instead of a function that defines its own this
context, use an arrow function:
const loading_done = () => {
console.log("Chatbot initialized!");
bot.sortReplies(); //sorting replies
let username = "user";
return bot.reply(username, msg).then(answer => { //getting chatbot answer
console.log("User: " + msg);
console.log("Chatbot: " + answer);
const result = answer;
const botMessage = new Message(result, 'bot');
this.update(botMessage);
});
}
As you are using typescript, you could also make loading_done a private function:
converse(msg: string) {
const userMessage = new Message(msg, 'user'); //gettng user message
this.update(userMessage);
var bot = new RiveScript({utf8: true}); // initializing bot
bot.loadFile('/assets/brain/test.rive').then(this.loadingDone); // loading bot brai
}
// Use camel case instead of snake case in typescript.
private loadingDone = () => {
console.log("Chatbot initialized!");
bot.sortReplies(); //sorting replies
let username = "user";
return bot.reply(username, msg).then(answer => { //getting chatbot answer
console.log("User: " + msg);
console.log("Chatbot: " + answer);
const result = answer;
const botMessage = new Message(result, 'bot');
this.update(botMessage);
});
}
try
converse(msg: string) {
const userMessage = new Message(msg, 'user'); //gettng user message
this.update(userMessage);
var bot = new RiveScript({utf8: true}); // initializing bot
const loading_done = (bot) => ()=> {
console.log("Chatbot initialized!");
bot.sortReplies(); //sorting replies
let username = "user";
return bot.reply(username, msg).then(answer => { //getting chatbot answer
console.log("User: " + msg);
console.log("Chatbot: " + answer);
const result = answer;
const botMessage = new Message(result, 'bot');
this.update(botMessage);
});
}
bot.loadFile('/assets/brain/test.rive').then(loading_done(bot)); // loading bot brain
}
or
loading_done(bot){
return ()=> {
const that = this;
console.log("Chatbot initialized!");
bot.sortReplies(); //sorting replies
let username = "user";
return bot.reply(username, msg).then(answer => { //getting chatbot answer
console.log("User: " + msg);
console.log("Chatbot: " + answer);
const result = answer;
const botMessage = new Message(result, 'bot');
that.update(botMessage);
});
}
}
converse(msg: string) {
const userMessage = new Message(msg, 'user'); //gettng user message
this.update(userMessage);
var bot = new RiveScript({utf8: true}); // initializing bot
bot.loadFile('/assets/brain/test.rive').then(this.loading_done(bot).bind(this)); // loading bot brain
}
but I believe the first solution is more clear
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.