简体   繁体   中英

Problem "Uncaught (in promise) TypeError" RiveScript chatbot in Angular

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM