Neoheurist
Neoheurist

Reputation: 3474

How to stop an Angular 2 component initialization and navigate to a default (safe) route

I have a situation where as a Component is initializing the component detects that the application is not in the proper state for the component to correctly load/operate. The component's ngOnInit method tries to navigate() to a safe page to prevent utter failure due to an undefined object's member being accessed within the template.

ngOnInit() {
  // when no scenario has been passed to the component:
  // try to get the active one from the application context via the scenario service

  if (null == this.scenario) {

    this.scenario = this.scenarioService.activeScenario;

    // when there's no current scenario set in the application context:
    // try to get one from the scenario service in the active period

    if (null == this.scenario) { 

      this.scenario = this.scenarioService.getScenariosByYear(this.settingsService.activePeriod)[0];

      // when there's no scenarios defined in the active period:
      // navigate to the the scenario manager component so the user can create one

      if (null == this.scenario) {

        this.router.navigate(['/scenario']); // <==== this doesn't seem to fire

      }
    }
  }
}

Question 1 : Why doesn't the this.router.navigate(['/scenario']); call work (interrupt the component lifecycle)?

Question 2 : Generically, is there a way to stop the component lifecycle during initialization to permit preemptive navigation to a safe place?

Upvotes: 6

Views: 9024

Answers (2)

Fiddles
Fiddles

Reputation: 2915

What you want is a guard. Guards can be used to prevent navigation to a route, or you can use them to intercept and redirect like you want in this case. See https://angular.io/guide/router#milestone-5-route-guards

Upvotes: 4

Neoheurist
Neoheurist

Reputation: 3474

At present it seems that Angular 2 does not provide a mechanism for the application to interrupt (stop) the component lifecycle and the rendering of the component template (and child components / templates).

A colleague recommended placing conditional processing / rendering logic on all properties within my parent component and all of the related child component properties to prevent erroneous access to undefined objects within my components. This approach surely would work, but seemed rather tedious to set up and even more painful to maintain, so I decided to tackle the problem at a slightly higher level...

Ultimately, my approach was to use a wrapping <div *ngIf="valid"></div> element around my parent component's template and place each of the subordinate child component templates within their own wrapping <div *ngIf="valid"></div> element. Doing this gave me the ability to stop the templates from rendering in the case of undefined objects. I then created a service to which the child components listen and for the parent component to signal when a valid instantiation of the parent component has occurred (e.g. no undefined objects exist).

If anyone might have a better suggestion for how to deal with this type of situation, please let me know.

Upvotes: 0

Related Questions