Solvedangular canDeactivate called with null as component when lazy loading

I'm submitting a ...

[X ] bug report => search github for a similar issue or PR before submitting

Current behavior
When trying to use a canDeactivate guard with a lazy loaded route, the component parameter is null

This might be a regression of #15626 but I have not seen the provider problem

Expected behavior
I expect to be able to get a reference to the lazy loaded component

Minimal reproduction of the problem with instructions
http://plnkr.co/edit/mkgL1GOuRdk2w2xgYkrL

The StartComponent will be lazy loaded as route ''
Click the link "Click Me!" to trigger a routing to another component, this also triggers the canDeactivate guard for the '' route.
However the CanDeactivateGuard.canDeactivate(component) will not get the StartComponent into it as a parameter, it will get null instead, so you cannot call functions on the StartComponent to see if you can deactivate or not.
You can see the problem in the console.

Angular version:
4.1.3

Browser:
I use chrome, but the problem is there in other browsers too, it does not seem to be browser specific in any way.

31 Answers

✔️Accepted Answer

@Ristaaf, I was having the same issue, but I realise that I was using the guard on the wrong place. instead of placing the Guard at the:

const routes: Routes = [
  {path: '', loadChildren: 'app/start/start.module#StartModule', canDeactivate: [CanDeactivateGuard]},
  {path: 'another', component: AnotherComponent}
  ];

Place it at the main route of your Start module:

@NgModule({
    declarations: [StartComponent],
    imports: [
        RouterModule.forChild([
        { path: '', component: StartComponent , canDeactivate: [CanDeactivateGuard], children: [
           ...
        ]}
        ])
    ]
})

At the Lazyload module definition, you are setting an "alias" for when to load the Module and its components. So basiclly it does have a component. You can place all the components/routes you want to protect from that point by placing them inside children Route property

Other Answers:

The solution for this issue is moving the canDeactivate to the lazy load module.
here is the route to start component:
{path: 'start', loadChildren: 'app/start/start.module#StartModule'}

create a route module file (start.route.ts) for the start component:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CheckoutComponent } from './start.component';
import { CanDeactivateGuard} from 'your path to guard'
const routes: Routes = [
{
path: '', component: StartComponent,
canDeactivate: [CanDeactivateGuard]
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})

export class StartRoutingModule { };

then import the above file to the start.module.ts

More Issues: