You are unable to access the property outside of the callback function of the XMLHttpRequest

Currently, I am attempting to retrieve data from an XMLHttpRequest's onreadystatechange callback. Logging the data works perfectly fine within the callback function. However, when I try to use this data outside of the callback function with this.processedData.next(xttp), it generates the following error:

core.js:5828 ERROR TypeError: Cannot read property 'processedData' of undefined
    at callbackXttp (output.service.ts:55)
    at XMLHttpRequest.xhttp.onreadystatechange [as __zone_symbol__ON_PROPERTYreadystatechange] (output.service.ts:35)
    at XMLHttpRequest.wrapFn (zone-evergreen.js:1202)
    at ZoneDelegate.invokeTask (zone-evergreen.js:400)
    at Object.onInvokeTask (core.js:40744)
    at ZoneDelegate.invokeTask (zone-evergreen.js:399)
    at Zone.runTask (zone-evergreen.js:168)
    at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:481)
    at invokeTask (zone-evergreen.js:1596)
    at XMLHttpRequest.globalZoneAwareCallback (zone-evergreen.js:1622)

The issue might be related to the asynchronous nature of the request. My attempt to address this involved using a callback function.

export class OutputService {

  processedData: ReplaySubject<any>;

  constructor(private router: Router) {
    this.processedData = new ReplaySubject<any>();
  }

  doCalculation(a, b, z) {
    this.request(a, b, z, this.callbackXttp);
  }

  request(a, b, z, callback) {
    const V = {classes: a, absolute: b, z};
    const Val = JSON.stringify(V);
    let response = 0;
    console.log('Request Data: ' + Val);
    const xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState === 4 && this.status === 200) {
        response = JSON.parse(this.responseText);
        callback(response);
      }
    };

    xhttp.open('POST', 'http://127.0.0.1:8000/', true);
    xhttp.setRequestHeader('Content-Type', 'application/json');
    xhttp.send(Val);
  }

  callbackXttp(xttp) {
    const object = [
      ...
    ];
    this.processedData.next(xttp);
    this.router.navigate(['/output']);
  }

  getProcessedData(): Observable<any> {
    return this.processedData.asObservable();
  }
}

An example call in another component:

this.outputService.doCalculation([1, 2, 3, 4, 5, 6], [2, 4, 5, 8, 3], 2);

Answer №1

You're passing this.callbackXttp as an argument to this.request:

  performCalculation(a, b, z) {
    this.request(a, b, z, this.callbackXttp);
  }

Later on, you are calling it like this:

callback(response);

Because you are calling it simply as a function, not something.callback(), the value of this inside callbackXttp will be undefined. This is why you encounter an error in this section:

this.processedData.next(xttp);

A possible solution is to use .bind on the function before passing it:

    this.request(a, b, z, this.callbackXttp.bind(this));

Answer №2

What would happen if you made the following adjustment:

this.request(a, b, z, this.callbackXttp);

to

this.request(a, b, z, xttp => this.callbackXttp(xttp));

Additionally, I presume there is a specific rationale for not utilizing the Angular HttpClient?

Edit:

In essence, it seems that your issue arises from using a traditional function here

xhttp.onreadystatechange = function() {
}

This results in the references to this. within callbackXttp pointing to the function rather than the class itself.

As an alternative to my previous suggestion, consider updating

xhttp.onreadystatechange = function() {
}

to

xhttp.onreadystatechange = () => {
}

(And then perhaps transitioning to the HttpClient...)

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

Files are nowhere to be found when setting up an angular project

After creating an Angular project, I noticed that some key files were missing in the initial setup, such as app.modules.ts and app-routing.modules.ts The project was generated using the command ng new name Here is a screenshot displaying all the files th ...

Preventing toggle from altering the width of the side navigation bar

Is there a way to prevent the width of the side bar from changing when toggling the top level items in the side nav bar, especially if the sub navigation items are wider? Click on 'Click me' in the side nav item to see what happens. Check out th ...

Exploring the usage of asynchronous providers in NestJS

I am currently utilizing nestjs and I am interested in creating an async provider. Below is my folder structure: . ├── dist │ └── main.js ├── libs │ └── dma │ ├── src │ │ ├── client │ ...

Transferring data via ajax from the View to ActionResult action method

Issue with data delivery from view to controller using AJAX in ASP.NET MVC project Description of the problem: function submit() { var obj = {}; obj.PD = getResult('pd'); obj.MD = getResult('md'); obj.C = getResult(&a ...

Firestore experiencing difficulty fetching / showing data

For some reason, Firestore is unable to retrieve or display data from a Collection named data. This issue emerged after I attempted to simplify my code. Take a look at the code snippet: Filename: database.component.ts import { Component, OnInit } from & ...

Creating a popup with multiple tabs using CSS

Struggling to navigate through the intricacies of these code snippets <!DOCTYPE html> <html lang ="en"> <head> <style type="text/css"> a{ text-decoration:none; color:#333; } #pop{ width:557px; height:400px; background:#333; ...

Rephrasing links with JavaScript, excluding links leading to a particular directory

I am facing an issue with my webpage where I need to rewrite links using Javascript. Specifically, all the links within the div id="container" need to be changed from "post=post-number-234" to "?id=blog&post=post-number-234". Currently, I have a scrip ...

Struggling to implement the .map method with TypeScript?

I'm currently grappling with incorporating TypeScript into my .map method and encountering the error message below. Additionally, I'm uncertain about the meaning of the 'never' keyword. TS2339: Property 'fname' does not exist ...

Combining the powers of AngularJS and Django

Just diving into the world of Django and AngularJs, feeling a bit lost. I have my data flowing in from an SQL database to a table and I'm struggling to implement sorting and searching functionalities. I have the basics covered with Django model and ...

Continue iterating only when all promises have been resolved

My AngularJS requirement involves the following: for (var i = 0, len = self.Scope.data.length; i < len; i++) { var data = self.Scope.data[i]; var self = this; //Executing First asynchronous function self.EcritureService.createNewDa ...

Implementing multi-select checkbox feature in Angular 7 using ng-select

I'm looking to create a function where selecting an item will make the corresponding div appear. For instance, if I choose Crédit bancaire and Compte courant associé, the two corresponding divs should be shown. Check out this example: https://stac ...

Tips on utilizing useStyle with ReactJS Material UI?

Is there a way to utilize a custom CSS file in the useStyle function of Material UI? I have created a separate useStyle file and would like to incorporate its styles. Can someone explain how this can be accomplished? input[type="checkbox"], inp ...

Adjust the preset timeout for mocha

In the scenario where we have a unit test file named my-spec.js and are utilizing mocha for running tests: mocha my-spec.js By default, the timeout period is set at 2000 ms. However, it can be modified for specific tests by adding a command line paramet ...

Turn on and off jquery tabs depending on user's choice

Currently, I am utilizing jQuery tabs to showcase specific data. However, I aim to offer users the flexibility to choose whether they prefer to view the content as tabs or in a sequential manner. Even after attempting to manipulate the ui-tabs classes ba ...

Displaying data-table with only the values that are considered true

Right now, I am utilizing the AgReact table to exhibit data fetched from my endpoints. The data-table is functioning properly, however, it seems to be unable to display false values received from the endpoints on the table. Below are the snippets of my cod ...

Sequentially transferring data to users and processing in Node.js

I am currently working on a website using node.js with express and socket.io. The server is set up to send photos and data from every file in a directory to the user using the socket.emit function. However, I have encountered an issue with the code where ...

"Utilizing Object.call() in JavaScript for inheritance yields an undefined result

I have been working on implementing an object-oriented approach in my program. According to what I've learned, there should be an inheritance relationship between World and Sprite classes, with Sprite as the parent. However, when I try to call Sprite. ...

Dealing with JavaScript errors within an Express application

Consider the following async function export async function fetchData() { const result = await fetchData(); return result[0].id; } In the route, there is router.post( '/some-route', handleAsyncError(async (req: Request, resp: Response, _ ...

Elevate sublevel vue component

I am facing an issue with a nested and reused vue component. I am attempting to use v-show to display a part of the component (icons) when its outer parent is hovered. In order to achieve this, I am passing the parent and child index as props. However, I ...

How do you toggle the visibility of a dependent <select> in an HTML form?

In my HTML jQuery form, I need to display a second select box based on the user's selection in the first select box. Should I use .show() to reveal a previously hidden div or should I use .append() to populate an empty select element? In other words, ...