Проблема «Неперехваченная (в обещании) Ошибка типа «чат-бот RiveScript в Angular

#javascript #angular #typescript #chatbot #rivescript

#javascript #angular #typescript #чат-бот #rivescript

Вопрос:

Я пытаюсь реализовать чат-бота на основе RiveScript в Angular. Чат-бот отлично работает — я всегда получаю правильный ответ в консоли. Отображение ввода пользователя тоже отлично работает. Однако я всегда застреваю в одной точке: отображение ответа чат-бота в пользовательском интерфейсе чата из-за следующей ошибки:

 ERROR Error: Uncaught (in promise): TypeError: this is undefined
  

Я действительно перепробовал так много вещей, но не могу найти проблему. С моей точки зрения, это также немного сбивает с толку, потому что я могу получить правильное сообщение чат-бота в консоли. Я был бы рад, если бы кто-нибудь мог помочь мне решить эту проблему!

Вот мой исходный код с комментариями и журналом консоли в виде скриншота. Итак, вы можете видеть, что код работает.

 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);
      }); 
    }
  }
  

Ответ №1:

попробуйте

 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

  }
  

или

    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

  }
  

но я считаю, что первое решение более понятно

Комментарии:

1. Ваше второе решение сделало свое дело. Большое вам спасибо!

Ответ №2:

Вместо функции, которая определяет свой собственный this контекст, используйте функцию со стрелкой:

 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);
      }); 
    }
  

Поскольку вы используете typescript, вы также можете сделать loading_done частной функцией:

 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);
      }); 
}
  

Комментарии:

1. bot не определен в loadingDone области действия функции

2. Я отредактировал свой второй фрагмент кода, там была небольшая ошибка.

3. Что касается объекта bot: я бы предложил инкапсулировать его в службу angular. приветствия.