What prevents me from utilizing the Router object within a function set for the then() of a CRUD delete operation in my Angular service?

I'm currently tackling a challenge in my Angular project where I am attempting to utilize a Router class to navigate to a specific page from within a service class. Allow me to elaborate on my predicament.

The service class in question looks like this:

@Injectable({
  providedIn: 'root'
})
export class PatientService {

 

  constructor(
              private firestore: AngularFirestore,
              private router: Router
             ) { }

    ........................................................................
    ........................................................................
    ........................................................................

  deletePatient(patientId) {
    console.log("deletePatient() START. patientId: " + patientId);
    this.firestore
        .collection("patients")
        .doc(patientId)
        .delete()
        .then(async function(docRef) {
          console.log("Patient successfully deleted!");
          //this.router.navigate(['/patients-list']);

        })
        .catch(function(error) {
          console.error("Error deleting document with ID: ", patientId);
          console.log("ERROR: ", error);

          // TODO: NAVIGATE ON THE USER DETAILS PASSING A PARAMETER IN ORDER TO PRINT AN ERROR MESSAGE
        });

        this.router.navigate(['/patients-list']);
    
  }
}

In the code snippet above, I am injecting private router: Router in the constructor and then utilizing it within the deletePatient() method.

Currently, the code works effectively and redirects me to the page specified by the patients-list route. However, this behavior is incorrect because I only intend to redirect to this page if the patient has been successfully removed from my Firestore database. Therefore, ideally, this navigation should occur inside the function defined for the then() block (after it prints out the message "Patient successfully deleted!" in the console).

The issue arises when attempting to do so in the following manner:

  deletePatient(patientId) {
    console.log("deletePatient() START. patientId: " + patientId);
    this.firestore
        .collection("patients")
        .doc(patientId)
        .delete()
        .then(async function(docRef) {
          console.log("Patient successfully deleted!");
          this.router.navigate(['/patients-list']);

        })
        .catch(function(error) {
          console.error("Error deleting document with ID: ", patientId);
          console.log("ERROR: ", error);

          // TODO: NAVIGATE ON THE USER DETAILS PASSING A PARAMETER IN ORDER TO PRINT AN ERROR MESSAGE
        });

        //this.router.navigate(['/patients-list']);
    
  }

When implementing it this way, the redirection does not take place and an error message appears in the Chrome console:

ERROR:  TypeError: Cannot read property 'router' of undefined
    at patient.service.ts:104
    at Generator.next (<anonymous>)
    at tslib.es6.js:74
    at new ZoneAwarePromise (zone-evergreen.js:960)
    at __awaiter (tslib.es6.js:70)
    at patient.service.ts:102
    at ZoneDelegate.invoke (zone-evergreen.js:364)
    at Object.onInvoke (core.js:27504)
    at ZoneDelegate.invoke (zone-evergreen.js:363)
    at Zone.run (zone-evergreen.js:123)

Why is it that the router object is not available from within the function defined for the then() case? Looking at the private router: Router injection in my service constructor, the IDE points out:

Property 'router' is declared but its value is never read.ts(6138)

Evidently, there seems to be some difficulty accessing the this.router property from within this function. But why? What could be missing? How can this problem be resolved to achieve the correct behavior? (Essentially, navigating to the /patients-list route after a successful deletion or to an error page upon encountering issues while deleting the patient)

Answer №1

Using an inline function will cause this to refer to the function call context rather than your class instance.

Instead of:

.then(async function(docRef) {
          console.log("Patient successfully deleted!");
          this.router.navigate(['/patients-list']);

 })
.catch(function(error) {

You can use an arrow function:

.then((docRef) => {
          console.log("Patient successfully deleted!");
          this.router.navigate(['/patients-list']);

})
.catch((error) => {

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

Best approach for managing Angular dependencies: Is it acceptable to link to a TypeScript file other than its corresponding component.ts in a component.html file?

My friend and I recently had a disagreement about a file in our project called experiment-row.component.html. The code in question looked like this: *ngIf="experimentsPageService.isRegularStatusIconVisible(experiment)" I argued that it is not go ...

What is the best way to dynamically bind values for ngclass in Angular Material?

[I need help with binding the 0th index of a splitted value to ngclass in my .html file without using backend. Can anyone provide assistance? Here is the code in my .ts file: response = "success&2018-12-19 09:26:03"; this.status = response; Thi ...

What could be triggering the "slice is not defined" error in this TypeScript and Vue 3 application?

I have been developing a Single Page Application using Vue 3, TypeScript, and the The Movie Database (TMDB) API. In my src\components\MovieDetails.vue file, I have implemented the following: <template> <div class="row"> ...

What is the process for exporting dynamic paths with the NextJS app using static methods

My webpage is located within the directory src/app/c/patient/[id]/page.tsx. Everything is functioning correctly when deployed, but I'm trying to export it to a js bundle for use with the Capacitor Android/iOS app. However, I encountered the following ...

Displaying a div component in React and Typescript upon clicking an element

I've been working on a to-do list project using React and TypeScript. In order to display my completed tasks, I have added a "done" button to the DOM that triggers a function when clicked. Initially, I attempted to use a useState hook in the function ...

I'm encountering an issue trying to apply array filtering with checkboxes using React hooks and TypeScript

Help needed! I'm facing an issue while trying to filter an array based on gender using checkboxes. The functionality works fine for the male checkbox but seems to fail when clicking on the female checkbox. Below is the code snippet from my App.tsx fil ...

Leverage the spread operator (or an equivalent method) to transfer all attributes from a solitary mixin

When working with the example below, my goal is to pass only the properties of MyMixedInProps to MyChildComponent using a method similar to the spread operator ({...props}). In my specific scenario, MyMixedInProps is defined in a third-party library (whic ...

Custom React component - DataGrid

Just starting out in the world of React and attempting to create a custom component with parameters. I'm curious about the correct approach for achieving this. Here's my current code snippet - how do I properly pass Columns, ajax, and datasourc ...

Personalized Angular calendar selector

Looking for an Angular datepicker with unique input features such as: Ability to navigate using keyboard (e.g. keydown for previous day, keyup for next day) within the input field itself (not just in the datepicker popup) Autocomplete functionality, for ...

Create a series of buttons in Angular 2 that are linked to components with a click event

I am facing an issue with a component that generates a list of buttons, where I want to connect the click event to show a child component. The problem is that my current implementation using a local variable causes all buttons to display the last child com ...

Having trouble getting angular and php to upload images?

I'm having trouble uploading images using Angular and PHP with the following code. Can someone please assist me? I'm getting an undefined index error on line 2 from the PHP side. const formData = new FormData(); formData.append('date', ...

Module not found when attempting lazy loading routing in Angular2 RC5

Having some challenges implementing RC5 changes in my app, particularly when it comes to lazy loading modules within the routing. Here's the file structure for the affected files in my app: /app /components/meda/meda.module.ts /components/meda ...

How can you display a single error message using Reactive Forms?

In Angular 7, I have implemented a Reactive Form with an input field named email. This input field is configured with two validators as shown below: email: ['', [Validators.email, Validators.pattern('^[\\w._]+@company(.com|.go|.je ...

Error in Redirecting to Localhost

Recently, I developed an Angular App that interacts with the MS Graph API using MSAL. Initially, everything worked smoothly when running "ng serve" in Angular CLI. However, I encountered a problem when I packaged this Angular App with electron to deploy i ...

Guide to getting started quickly with Angular 2: troubleshooting tips

Hey there everyone! So I've encountered some challenges while diving into the world of Angular. Initially, I followed thenewboston's Angular 2 tutorial. After completing that, I moved on to Angular's quick start tutorial. Both tutorials are ...

Is there a way to retrieve the latitude and longitude values using a plugin and then make a web service call in Ionic with Angular 5?

I am currently trying to retrieve the latitude and longitude coordinates of a location by using geocode in Angular 5 within the Ionic framework. Once I have obtained the lat long, I intend to pass it to my service. The issue I am facing is that my service ...

What is the best way to reference typescript files without using absolute paths?

As typescript does not seem to have built-in support for absolute path references (according to this GitHub issue), it becomes difficult to organize and maintain my file references. With TypeScript files scattered across various locations in my folder stru ...

Eliminate the unnecessary code repetition in my functions using Typescript

I have 2 specific functions that manipulate arrays within an object. Instead of repeating the same code for each array, I am looking for a way to create reusable functions. Currently, my functions look like this: setLists(): void { if (this.product.ord ...

Creating Dynamic CSS Styling with Vendor Prefixes in Angular 2

I am exploring how to create a component in Angular 2 with two input arguments: colorOne and colorTwo. The goal is to fill a <div> with a gradient of these two colors. If I simply wanted to set the div background color to colorOne, I could achieve t ...

IssueTS1128Compilation: Syntax error, declaration or statement is missing in Angular 2

After updating my ASP.NET Core 1.0 dependency to ASP.NET Core 1.1 using the NuGet manager, I have encountered an error: Error TS1128 Build:Declaration or statement expected. Upon researching, I discovered that the issue lies in me using an outdated vers ...