Bryan
Bryan

Reputation: 3009

Getting properties from wrong component in CanDeactivateGuard

I am following the component-specific can-deactivate.guard.ts example found here: https://angular.io/guide/router#candeactivate-handling-unsaved-changes

This guard accesses properties from another component, and I am struggling to get that to fully work with my app.

I have a container called MessagesComponent and a child component called FormComponent. I'm importing the child component into the guard the same way the example is doing with CrisisDetailComponent. My problem is that when I try to access properties from FormComponent, the only ones that are actually available to me or the ones coming from my container (MessagesComponent), which I'm not importing into the guard. How do I access the properties from my child component instead? Here is my code:

guard:

import { FormComponent } from '../components/form/form.component';
...

export class CanDeactivateGuard
    implements CanDeactivate<FormComponent> {
    constructor(
        public dialog: MatDialog,
    ) {}
    canDeactivate(
        component: FormComponent,
    ): Observable<boolean> | boolean {
        console.log('component', component);
        ...
    }
}

routing:

...
{
  path: 'messages',
  component: MessagesComponent,
  canDeactivate: [CanDeactivateGuard],
},
...

Everything that comes back from my console log is properties from MessagesComponent. Why is that happening when I'm importing FormComponent?

Upvotes: 0

Views: 315

Answers (1)

bjdose
bjdose

Reputation: 1309

Actually you are importing the FormComponent as a type in the CanDeactivateGuard. But you are passing the MessagesComponent. Maybe Angular could throw an error but that is not happening.

In order to clarify, I wrote some code.


    component: MessagesComponent, // this is the component which you're passing to canDeactivate
    canDeactivate: [CanDeactivateGuard], // you are passing the messages component to the canDeactivate method

    ...

    canDeactivate(
        component: FormComponent, // <- you have FormComponent as a type, but this method actually is receiving MessagesComponent
    )

If you want to see your form component on the browser console, you need to pass it.


    component: FormComponent,
    canDeactivate: [CanDeactivateGuard],

    ...

    canDeactivate(
        component: FormComponent, // <- now you can see your form component, and the type is useful to see all the properties and methods which form component has inside itself
    )

In your case, you could use the view child decorator to get the child component and use it in the guard.


    export class MessagesComponent {
      @ViewChild(FormComponent) formComponent: FormComponent;
    }

    ...

    component: MessagesComponent,
    canDeactivate: [CanDeactivateGuard], 

    ...

    canDeactivate(
        component: MessagesComponent,
    ) {
      console.info('magic', component.formComponent);
    }


Upvotes: 1

Related Questions