Error: Unhandled promise rejection - component.canDeactivate is undefined

I encountered an error while setting up my CanDeactivateGuard.

Uncaught (in promise): TypeError: component.canDeactivate is not a function

To ensure reusability, I decided to create a generic version of the CanDeactivateGuard.

For this purpose, I crafted an abstract class called ComponentCanDeactivate and then extended it in the TreeCanDeactivateGuard.

The CanDeactivateGuard should implement the interface CanDeactivate.

Here's a snippet of my code:

import { HostListener } from '@angular/core';

export abstract class ComponentCanDeactivate {

  public abstract canDeactivate(): boolean;

  @HostListener('window:beforeunload', ['$event'])
  unloadNotification($event: any) {
    if (!this.canDeactivate()) {
        $event.returnValue = true;
    }
}

}

The TreeCanDeactivateGuard :

import { ComponentCanDeactivate } from './canDeactivate/component-can-deactivate';
import { NodeService } from '../tree/node.service';


export abstract class TreeCanDeactivateGuard extends ComponentCanDeactivate {

    constructor(private _nodeService: NodeService) {
    super();
    }

    public canDeactivate(): boolean {
      if (this._nodeService.treeChangesTracer === false) {
          return true;
       } else {
          return false;
      }
}

}

The CanDeactivateGuard:

   import { Injectable } from '@angular/core';
    import { CanDeactivate } from '@angular/router';
    import { ComponentCanDeactivate } from './component-can-deactivate';

    @Injectable()
    export class CanDeactivateGuard implements CanDeactivate<ComponentCanDeactivate> {

        constructor() { }
         canDeactivate(component: ComponentCanDeactivate): boolean {

            if (!component.canDeactivate()) {
                if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
                    return true;
                } else {
                    return false;
                }
            }
            return true;
        }
    }

Routes Module :

const routes: Routes = [
{
    path: '', component: TreeComponent, canDeactivate: [CanDeactivateGuard] , runGuardsAndResolvers: 'always',
}]

Answer №1

What exactly is the purpose of TreeCanDeactivateGuard? I couldn't find any references to it in your code.

In order for TreeComponent to have access to the functionalities of ComponentCanDeactivate, it should extend that instead of TreeCanDeactivateGuard.

Ensure all components extend ComponentCanDeactivate and implement the canDeactivate method, so you can then utilize the general guard CanDeactivateGuard for all components.

You might also consider replacing the following block of code:

if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
   return true;
} else {
   return false;
}

With:

return confirm('You have unsaved changes! If you leave, your changes will be lost.');

Answer №2

Directly invoking an abstract method from an abstract class is not allowed; it must be called through a subclass. For example:

     deactivateComponent(component: TreeCanDeactivateGuard): boolean {

        if (!component.deactivate()) {

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

Facing a Bad Request error while trying to submit a Django Rest Framework Post request that appears to be valid, but is requiring a

Currently, I am in the process of creating a new instance of the SearchNeighborhood object and establishing a connection with an already existing SearchCity object through a POST request. The models I have set up are as follows: class SearchCity(models.M ...

Tips for handling a function only after the model window has returned a promise in Angular 2

When a button is clicked, three functions are called in sequence within a promise. The first function is responsible for blocking a model window and returning a promise which then resolves the next function. The HTML code snippet is as follows: ...

Inquiry regarding Typescript's array of types

While researching how to declare arrays of types online, I came across the following example: arrayVar: Array<Type> Seems simple enough, so I attempted to declare my variable like this: transactions: Transactions = { total : 0, list: Array<Transa ...

SSR routing with parameters in Angular Universal seems to be failing after intial navigation

I'm currently experiencing an issue with routing using path parameters: Navigation works perfectly when moving between categories initially, but once I navigate from one category to another, the routing doesn't update even though the URL in the ...

Encountering CORS issue while attempting to update information in Angular 9

Whenever I try to use the header in the following manner, everything works fine. However, I encounter a CORS error when attempting to use the put method. Despite multiple attempts, manually hard-coding the body did not resolve the issue and the CORS error ...

Executing a service call test within my component's unit test

Is there a simple way to test if my service is being called? myComp.ts constructor(private myService: MyService) {} myFunction() { this.myService.someFunction(); } myTest.ts beforeEach(async(() => { TestBed.configureTestingModule({ imp ...

Retrieve a collection of Firestore documents based on an array of unique identifiers

I have a Firestore collection where one of the values is an array of document IDs. My goal is to retrieve all items in the collection as well as all documents stored within the array of IDs. Here is the structure of my collection: https://i.sstatic.net/rA8 ...

The color attribute for the ion-button element is not functioning properly on Android devices in

In my app, it functions correctly when running on iOS, but encounters issues when running on Android. The problem lies in the color attribute not working on buttons and other elements on Android. Removing the attribute makes them visible, but the desired s ...

Angular 10 and Typescript: Variables assigned within the change event become undefined

In my code, I initialize an Algolia input and set an onchange event to it. This initialization takes place in a service. algolia_data; random_var; this.http.post<any>('APIENDPOINT', formData).subscribe(data => { instance = places({ ...

Using Lodash to Substitute a Value in an Array of Objects

Looking to update the values in an array of objects, specifically the created_at field with months like 'jan', 'Feb', etc.? One way is to loop through using map as demonstrated below. However, I'm curious if there's a more co ...

Angular Universal causing issues with updating the DOM component

@Component({ selector: 'mh-feature-popup', template: ` <div class="full"> <div> <div class="container-fluid" [@featurepop]="state"> <div class="row"> <div class="col-xs-12 col-md-4 col-md-offse ...

Angular: The specified function name cannot be called

My approach involves assigning an imported function to a component property within the constructor so that it can be utilized in the template. Although builds are successful, an error appears in my editor (Visual Studio Code with Angular Language Service) ...

Is it possible for Angular's `HttpClient` to use complex property types in the `.get()` generics aside from just `string` or `number`?

After spending an entire day researching the topic, I've hit a dead end. All my efforts have only led me to discover one thing—omission. None of the information I've come across mentions whether you can utilize non-simple types (such as string ...

Typing in a number will always activate the change event

Having trouble with Angular's change event on numeric input? It doesn't always trigger when clicking the increment or decrement buttons - it only triggers once and then requires the input to lose focus before triggering again. Is there a way to ...

Using React Typescript to create a button component with an attached image

I am currently utilizing React with Typescript. How can I incorporate an image into my button? I've attempted to do so without any errors, but the button appears blank. What's the best way to style my button element using Emotion CSS in this ...

Error in Angular Google Maps Component: Unable to access the 'nativeElement' property as it is undefined

I am currently working on creating an autofill input for AGM. Everything seems to be going smoothly, but I encountered an error when trying to integrate the component (app-agm-input) into my app.component.html: https://i.stack.imgur.com/mDtSA.png Here is ...

An obstacle encountered when implementing feature module services in a controller for a Nest JS microservice

Recently, I developed a feature module named "user" which includes a controller, model, and services to interact with my postgres database. Despite setting up everything correctly, I encountered an error when trying to call userService from the feature mod ...

Harmonize the connectivity between an Angular - .NET application and the Google Calendar API

I am currently working on integrating the Google Calendar API into my angular .NET application using OAuth2. The goal is to allow each user to see their own calendar as soon as they log in. One idea I have is to save the generated code into our database f ...

Is there a way to merge my local store with Firestore using ngrx entity?

Currently, I'm facing a challenge while using NgRx and Firestore as I attempt to keep the local store in sync with a firestore collection. I have set up an observable that triggers when the firestore collection is updated. However, in my reducer, I am ...

Using React's higher order component (HOC) in TypeScript may trigger warnings when transitioning from non-TypeScript environments

I have a simple HOC component implemented in React with TypeScript. export const withFirebase = <P extends object>( Component: React.ComponentType<P> ) => class WithFirebase extends React.Component<P> { render() { return ...