Route Guard - need help with calling component function

I try to implement route guard that need check is profile valid, but the function checkIsValid is not called

profile.guard.ts

import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { ProfilePage } from '../../pages/profile/profile.page';

@Injectable()
export class ProfileFormGuard implements CanDeactivate<ProfilePage> {
  constructor() {}
  canDeactivate(
    component: ProfilePage,
  ): Promise<boolean> {
    console.log('ProfileFormGuard'); // logged
    const isValid = component.checkIsValid();
    console.log('ProfileFormGuard isValid', isValid);  // not logged
    return new Promise(async (resolve, reject) => {
      resolve(isValid);
    });
  }
}

profile.page.ts

...
@Component({
  selector: 'app-profile',
  templateUrl: './profile.page.html',
  styleUrls: ['./profile.page.scss']
})
export class ProfilePage implements OnInit {
  public checkIsValid() {
    console.log('checkIsValid'); // not logged
    return true;
  }
...
}

what is wrong there, thank you

If you debug a bit more, is component in the Guard set to the correct one? ProfilePage in this case?

yes, I need to check is profile form is valid

what is logged if you log

console.log(component.checkIsValid);

in the guard?

seems log not invoked (nothing logged even empty line) and following logs also not invoked (

console.log(component); logged null

That’s what i mean here. Please show your routing, how are you using the guard.

I have tabs route that part of app route:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { TabsPage } from './tabs.page';
import { AuthGuard } from '../../services/user/auth.guard';
import { ProfileFormGuard } from '../../services/user/profile.guard';

const routes: Routes = [
  {
    path: 'tabs',
    component: TabsPage,
    children: [
      ...
      {
        path: 'profile',
        loadChildren: () => import('../profile/profile.module').then(m => m.ProfilePageModule),
        canActivate: [AuthGuard],
        canDeactivate: [ProfileFormGuard],
      },
      {
        path: '',
        redirectTo: 'foo',
        pathMatch: 'full'
      },
      {
        path: '**',
        redirectTo: 'foo',
        pathMatch: 'full'
      },
    ],
  },
  {
    path: '',
    redirectTo: 'tabs',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: 'login',
    pathMatch: 'full'
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: [ProfileFormGuard],
})
export class TabsPageRoutingModule { }

I guess there is the problem. You are not using the Guard in combination with a component, you use it instead of a submodule. Try setting the Guard in the submodule routes where you have:

{
  ...
  component: ProfilePage,
  ...
}
1 Like

I have tried this, but app hangs somewhere after executing splashScreen.hide

export class AppComponent {

  constructor(
    private authService: AuthService,
    private platform: Platform,
    private splashScreen: SplashScreen,
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      setTimeout(() => {
        console.log('splash hidden'); // after this nothing logs any more
        this.splashScreen.hide();
      }, 1000);
    });
  }

What has this to do with the question we are discussing?

Now I understand where error, I have to update my component router (profile-routing.module.ts instead of tabs-routing.module.ts):

const routes: Routes = [
  {
    path: '',
    component: ProfilePage,
    canDeactivate: [ProfileFormGuard],
  }
];

Bro thats exactly what i said before :joy:

thank you, have a nice day! )

Since canDeactivate can return an ordinary boolean, why are you instantiating a Promise here? Why not just return component.checkIsValid() directly?