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)