There seems to be an issue with accessing the 'request' property of an undefined object

Currently, I am in the process of incorporating a base service into an Angular application. This service is designed to provide methods to other services for composing requests with default headers and options. However, I encounter an issue when attempting to call the get or post methods. These methods simply invoke this.request, but I am encountering a ZoneAwarePromise error.

ERROR Error: Uncaught (in promise): Cannot read property 'request' of undefined
    at resolvePromise (zone.js:831)
    at zone.js:896
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17280)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at drainMicroTaskQueue (zone.js:601)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
    at invokeTask (zone.js:1744)
    at HTMLButtonElement.globalZoneAwareCallback (zone.js:1770)
defaultErrorLogger  @   core.js:15714
...

This error is perplexing because I have confirmed that this.request exists by logging its value before using it within the post method.

interface Options {
  payload?: any,
  headers?: any,
  options?: any
}

@Injectable()
export class ApiService {
    private host: string = `${environment.apiUrl}`;

    constructor(private http: HttpClient) {}

    public get(route: string, options?: any) {
        return this.request(route, 'GET', options);
    }

    public post(route: string, options?: any) {
        return this.request(route, 'POST', options);
    }

    public setToken(token: string) {
        localStorage.setItem('Token', token);
    }

    public unsetToken() {
        localStorage.removeItem('Token');
    }

    private request(route: string, method: string, requestOptions?: any): Promise<void> {
        return new Promise((resolve, reject) => {
            ...
        });
    }
}

I am seeking assistance to resolve this error and successfully call the request method without encountering any issues.

EDIT

The post method is being called within the following login method:

@Injectable()
export class AuthService {
    private user: any = null;

    constructor(private service: ApiService) {
        ...
    }

    ...
}

Answer №1

Understanding the concept of this in JavaScript is crucial, as it is determined by the function's runtime binding.

When calling the http post method internally, it invokes the 'request' method on the http object. However, if you reference the post and invoke it, the this reference may become undefined in strict mode.

An alternative approach is to directly use the http object.

  private request(route: string, method: string, requestOptions?: any): Promise<void> {
      return new Promise((resolve, reject) => {
          const url = new URL(route, this.host);
          const { payload, headers, options }: Options = requestOptions || {};
          const defaultHeaders = { 'Content-Type': 'application/json' };
          const token = localStorage.getItem('Token');
          if(token) { defaultHeaders['Authorization'] = token; }

          const optionsDefinition = {
                  ...options,
                  withCredentials: true,
                  headers: new HttpHeaders({...defaultHeaders, ...headers})
          };

          this.http[method.toLowerCase()](url.toString(), payload, optionsDefinition)
              .subscribe(() => {console.log('resolve'); resolve();},
                  () => {console.log('reject');reject(); });
      });
  }

Another method to address the issue with the this object is by using the bind method.

   const fn = this.http[method.toLowerCase()].bind(this.http);

Check out the demo 🚀🚀

Explore more about 'this' 🧙‍♂️

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

The script is not functioning properly when placed outside of the HTML body tag

I have a main template that is functioning properly with the layout I've included here. However, I am facing an issue when trying to organize the scripts within one block. Specifically, when I move one of the scripts from the body section to the head ...

Link Google Map Marker Click Event with Dynamic Binding

I'm currently working on binding a click event to a link that is positioned outside the Google Map Canvas. The goal is to open an "infowindow" on a map marker when this link is clicked. While I know how to achieve this for a specific point, I need a d ...

Creating an uncomplicated search bar that dynamically adjusts values based on its function

Summing it up, there is a div situated within my app.component.html: <div class="col-lg-6 search-div"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search for..."> <span class="input-group-b ...

Display the Bootstrap datepicker within an h4 element set to default to today's date, utilizing both Angular and jQuery

Utilizing Boostrap datepicker to obtain the selected date from the calendar and insert it into an <h4> html tag. However, my goal is to display today's date by default in the h4 when it opens for the first time. Using angular.js + jquery f ...

Angular App Failing to Validate Session Cookie 'sessionId' in AuthGuard

Encountering a perplexing issue with my Angular application where the AuthGuard fails to recognize a session cookie named 'sessionId' correctly. I have successfully implemented user authentication, and the expected behavior is for users to be dir ...

Animating CSS with jQuery for a background image effect

I have the following JavaScript code : $(".linksColl a li").hover(function () { $(this).css({ "background-image" : "url(images/links/linkHover1.png)", "background-position" : "center center", ...

"Successful implementation of Ajax function in local environment but encountering issues when running online

I am facing an issue with my AJAX function. It works perfectly fine on my local server but does not return anything when I move it to my online server. Below is the code snippet: This is the part of the page where I call the showEspece() function: echo ...

What is the best way to continuously compare two date variables every minute using Javascript?

In my script, I have two date variables - one representing the current time and the other two minutes later. My goal is to compare both values every minute and trigger a function when the current time is greater than or equal to the latter time. Unfortun ...

Title remains consistent | Angular 4

Struggling to change the document title on a specific route. The route is initially set with a default title. { path: 'artikel/:id/:slug', component: ArticleComponent, data: {title: 'Article', routeType: RouteType.ARTICLE, des ...

Installing Vue JavaScript using the npm command

Embarking on my journey as a Vue JS learner, I took the plunge to install Vue and delve into creating web applications using it. So, I globally added npm Vue. npm install --global vue-cli This action resulted in: npm WARN deprecated [email protected]: T ...

The code inside the promise .then block is executing long before the promise has completed its

After spending quite some time working on this messy code, I finally have a functioning solution: loadAvailabilities() { let promises = []; let promises2 = []; let indexi = 0; //return new Promise((resolve, reject) => { this.appo ...

Guide to dynamically implementing pagination through AJAX calls

In this javascript code snippet, I have a class named PurchaseHistory. var baseUrl = null; var parameters = null; var currentPageNumber = null; var TotalPages = null; var PageSize = null; $(document).ready(function () { baseUrl = "http://localhost/AP ...

Angular4 allows for the creation of a div that can horizontally scroll

Below is the HTML code I am working with: <div class="card-deck" fxLayout.xs="row" style="overflow: scroll; height:100%"> <md-card style="width:10rem" *ngFor="let make of filteredMakes" (click)="goToModels(make.niceName)" class=" ...

Working with Ruby on Rails by editing a section of embedded Ruby code in a .js.erb file

Currently, I am in the process of developing a single-page website and have successfully implemented ajax loading of templates to insert into the main content section. However, I am encountering difficulties when trying to do this with multiple templates u ...

Tips for deactivating data monitoring in a Vue.js component attribute

Looking to develop a Vue.js component that accepts properties from its parent component, like this example: <table-cell :value="foo" format="date" /> Although value and format are set as properties, Vue automatically sets up obse ...

I require the variable to be accessible from all corners

Is there a way to access the variable "finalPrice" in a different function? I'm trying to achieve this and could use some guidance. function available(id){ $.ajax({ method:"GET", }).done(function(data){ for( ...

JavaScript button mouse enter

There seems to be an issue with this code. The button is not functioning properly after hovering over it, even though it was copied from the instructional website where it works fine. <html> <head> <title>Button Magic</t ...

Dealing with the element not present error in Protractor can be managed by using various

Is there a way to achieve similar Exception handling in Protractor as we can with Selenium webdriver in Java? When dealing with element not found exceptions, what is the most effective approach to handle them using Protractor? ...

Dealing with Typescript in Node.js: Handling the error 'Property not found on type Global & typeof globalThis'

I recently encountered an issue with my NodeJS app that is built with typescript and global.d.ts file. The strange part is that everything works fine in my old application, but when I try to run the new one using ts-node-dev ts-main-file.ts, I encounter an ...

What could be preventing the webpack dev server from launching my express server?

Currently working on a straightforward web application using express and react. The front-end React bundle is being served via the express server. Everything runs smoothly with my start script, which builds the front-end code and launches the express serv ...