Issue: Encounter of "Uncaught (in promise) TypeError" while implementing RiveScript chatbot in Angular

I've been working on integrating a chatbot based on RiveScript into Angular. The chatbot is functioning well - I always see the correct response in the console. Displaying the user's input is also working seamlessly. However, I'm encountering an issue when trying to display the chatbot's response in the chat UI due to the following error:

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

I've experimented with various solutions but haven't been able to pinpoint the problem. It's slightly perplexing because I can retrieve the correct chatbot message in the console. Any assistance in resolving this issue would be greatly appreciated!

Below is my source code along with comments and a console log for reference. This should demonstrate that the code is functional.

converse(msg: string) {

    const userMessage = new Message(msg, 'user'); // capturing 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 => { // fetching chatbot answer
        console.log("User: " + msg);
        console.log("Chatbot: " + answer);
        const result = answer; 
        const botMessage = new Message(result, 'bot');  
        this.update(botMessage);
      }); 
    }
  }

Answer №1

attempt

converse(msg: string) {

    const userMessage = new Message(msg, 'user'); //retrieving user message
    this.update(userMessage); 
   
    var bot = new RiveScript({utf8: true}); // initializing the bot
     
    const loading_finished = (bot) => ()=> {
      console.log("Chatbot is ready!"); 
      bot.sortReplies();  //arranging replies 
    
      let username = "user";
      
      return bot.reply(username, msg).then(answer => { //obtaining chatbot response
        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 the bot's brain

  }

or

   loading_executed(bot){ 
return  ()=> {
const that = this;
      console.log("Chatbot initialized!"); 
      bot.sortReplies();  //arranging replies 
    
      let username = "user";
      
      return bot.reply(username, msg).then(answer => { //obtaining chatbot response
        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'); //retrieving user message
    this.update(userMessage); 
   
    var bot = new RiveScript({utf8: true}); // initializing the bot
     


  bot.loadFile('/assets/brain/test.rive').then(this.loading_done(bot).bind(this)); // loading the bot's brain

  }

however, I feel the initial solution is more straightforward

Answer №2

Choose to utilize an arrow function instead of a function that defines its own this context:

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

Incorporate the concept of making loading_done a private function since you are using TypeScript:

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
  }

// Employ camel case over 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);
      }); 
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error with Bootstrap 4 tabs and JavaScript AJAX implementation

I have implemented Bootstrap 4 tabs to showcase content fetched through an AJAX call. However, I encountered an issue upon completion of the call. The error message displayed is: Uncaught TypeError: $(...).tab is not a function The tabs are initially hi ...

Hold off until the operation finishes executing and then deliver Angular 6

Is there a way to delay the subscribe function until my logic is complete and the transform method has updated the keys object? transform(value: any, args:string) : any { let keys = []; this.http.get('src/app/enum-data/enum.json').subsc ...

Using JavaScript to Retrieve, Manipulate, and Merge JSON Data from Various Files

My knowledge of JavaScript is limited, but I am interested in uploading multiple JSON files, processing them, converting them to text, combining them, and downloading them into a single JS file. I have successfully achieved this for a single file, but I a ...

Is it possible to utilize terms such as 'calc' within the [style.width] directive?

Can I incorporate my variable into calc() within the [style.width] directive in angular? For example: <div [style.width.px]="calc(100% - myWidth)">some texts </div> ...

Show off a font-awesome icon overlapping another image

My task involves fetching image source from a JSON file and then displaying it on an HTML page. https://i.sstatic.net/coOaU.png I also need to overlay a Font Awesome icon on top of the image as shown below: https://i.sstatic.net/nbrLk.png https://i.sst ...

Vue.js event handlers

I am in the process of creating a basic app that will include a few listeners. However, I am struggling to determine the best approach for organizing the logic behind it. Here is an example of the HTML: <div id="playerProgressBar"> <div id=" ...

Tips for retrieving nested objects in a get request

A dilemma I'm facing involves a form that effectively sends and saves JSON data to MongoDB using mongoose. However, the issue arises when attempting to access this data as the nested objects display on the get route html page as: { synth: { patch_na ...

Utilizing YouTube API information with AngularJS

I am currently working on a project where I need to fetch all the playlists from a specific channel and then display the name of each playlist in my AngularJS application. var myApp = angular.module('app', ['ngResource']); myApp.facto ...

Check and validate the adjacent field whenever a change is detected in this field in Angular

Currently, I have a select menu with options and a text field that accepts numerical input. The text field needs to adhere to specific ranges based on the selection from the select menu, which is managed through custom validation. My dilemma lies in trigge ...

How can you access the index of an object in Vue.js when one of its properties has been modified

Here's the Vue component code I'm working with: data: function () { return { products: [ { product_id: '', price: ''}, { product_id: '', price: ''}, ], ...

Extract the value from JSON data

I am faced with the challenge of extracting the value of slug from each child in a JSON dataset. The issue lies in the fact that I cannot predict how many children will be generated whenever new data is received. The generation of nested children is dynam ...

Could you please explain the significance of /** @docs-private */ in Angular's TypeScript codebase?

After browsing through the @angular/cdk code on GitHub, I came across a puzzling "docs-private" comment. Can anyone explain its significance to me? Link to Code * In this base class for CdkHeaderRowDef and CdkRowDef, the columns inputs are checked for ...

I'm currently attempting to establish a connection between my server.js express API and MongoDB, but I keep encountering an unfamiliar error message that I'm having trouble decipher

Here is the server.js code: import express from 'express'; import bodyParser from 'body-parser'; import userRoutes from './routes/users.js'; import mongoose from 'mongoose'; co ...

Tips on incorporating a hyperlink into an object imported through GLTF loader

Is there a way to include a hyperlink in the object loaded using gltf loader with the given code snippet below? var loader = new THREE.GLTFLoader(); var mesh; loader.load('globe.glb', function(gltf){ console.log(gltf); me ...

Determining the pageY value of a div element with overflow-y styling

Currently, I have implemented a script that tracks the mouse's position upon hover. My goal is to integrate this script within a div that has overflow-y: scroll The script currently utilizes pageY which identifies the position relative to the windo ...

Populate DataTables with data from JSON or JavaScript arrays and objects

Using jQuery(html), I was populating a table with data but now I am attempting to limit the displayed rows by switching the table to datatables. The data structure looks like this: dataArray = [{ id: 1, props: { abc: 123, def: 456 ...

Developing an Angular project may result in an overflow of memory

After attempting to construct an Angular project on a Linux server with the -aot flag, I encountered an error. Despite upgrading my instance to a higher CPU core, increasing RAM, and enabling a SWAP partition, the error persisted and even occurred more rap ...

Utilizing Express REST API with Postgres through the HTTP method

I am currently working on implementing REST APIs with Express and Postgres. I have a scenario where I need to delete all instances from a table based on the user_id foreign key, and then insert new instances with the same user_id. I'm unsure which HTT ...

What is the process of extracting data from a variable and inserting it into a JSON object in JavaScript?

I have just started learning about JSON and am currently working on a JavaScript program. I've been searching for a straightforward solution, but I may not be framing my question correctly. My goal is to allow users to input their information which w ...

What is the best way to trigger a re-render of a component in React?

Currently, I am in the process of building my very first full-stack website. After a user signs in, their information is stored in the localStorage. The goal is to display the user's name in the header once they are logged in. However, my header is no ...