Angular 4 ngOnInit not called after router.navigate

喜你入骨 提交于 2019-12-03 06:06:21

Please try adding router event in employee component. So that every time when /employee url state is routed it will fetch the employee details.

employee.ts component

constructor(private employeeService: EmployeeService, private router:Router) 
{ }

ngOnInit() {    
  this.router.events.subscribe(
    (event: Event) => {
           if (event instanceof NavigationEnd) {
                this.employeService.getEmployees().subscribe(res => this.employeeObj = res);
           }
    });
}

As a general rule, when routing, the angular router will re-use the same instance of a component if it can.

So, for example, navigating from /component/1 to /component/2, where the url is mapped to the same component (but with different params) will cause the router to instantiate an instance of Component when you navigate to /component/1, and then re-use that same instance when you navigate to /component/2. Based on what you're describing (where ngOnInit is only being called once), it seems as though this is what you're encountering. It's hard to say for sure, without seeing your templates and your route configuration. I know you say that your URL is changing from /employees to /form, but that may not matter, depending on how your templates and route configuration is set up. You can post that code (your templates and router configuration) here for examination if you wish.

Barring that, another option is that the router exposes all its events as a stream. So, you can subscribe to that stream and act on that, rather than just relying on ngOnInit.

In your employee.component.ts

.....
export class EmployeesComponent implements OnInit {

.....

ngOnInit() {


   this.router.events
              // every navigation is composed of several events,
              // NavigationStart, checks for guards etc
              // we don't want to act on all these intermediate events,
              // we just care about the navigation as a whole,
              // so only focus on the NavigationEnd event
              // which is only fired once per router navigation
              .filter(e => e instanceof NavigationEnd)
              // after each navigation, we want to convert that event to a call to our API
              // which is also an Observable
              // use switchMap (or mergeMap) when you want to take events from one observable
              // and map each event to another observable 
              .switchMap(e => this.employeeService.getEmployees())
              .subscribe(res => this.employeeObj = res);    
}

EDIT

I am seeing one piece of weird code:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { EmployeeService } from '../../employee.service';
import { Router } from '@angular/router';

@Component({
    selector: 'app-form',
    templateUrl: './form.component.html',
    styleUrls: ['./form.component.css'],

})
export class FormComponent implements OnInit {
  empform;

  ngOnInit() { 
    this.empform = new FormGroup({
      empname: new FormControl(""),
      joindate: new FormControl(""),
      salary: new FormControl("")
    })
  } 

  constructor(private employeeService: EmployeeService, private router:Router) { }

 onSubmit(user){   // <--  change this line
    this.employeeService.addEmployee(user)
    .subscribe(
        (response) => { this.router.navigate(['/employees']); }  
    );

  }
}

But overall, you are saying that if you navigate to your employee component, then to your form component and then back to your employee component, when you hit the employee component the second time, your employee list doesn't refresh.

Can you use console.log statements to ensure that ngOnInit is being called multiple times in your screen flow above? Because, based on your router configuration, when you navigate to employee list to form and back, your employee component should be re-initialized (by calling ngOnInit again)

When your component is linked with a route, better to add your code in the constructor subscribing to ActivatedRoute params and forcing change detection eg:

constructor(private route: ActivatedRoute, private changeDetector: ChangeDetectorRef) {
    super();
    this.route.params.subscribe((data) => {
    */update model here/*
    this.changeDetector.detectChanges();
   } 
}

If you downgrade @angular/router@4.1.3 seems to be working where on routerLink if you navigate it will trigger ngOnInit

Make sure you have <route-outlet></route-outlet> inside app.component.html. This should work just fine with the latest version of Angular 5.

What I think it happens is your route call is outside the Angular lifecycle because you are doing an async call right?

First check if your log show something like this:

WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'

If this is the case the solution is really simple, you have to tell Angular to call your routing directive inside their lifecycle.

Next code should fix your problem:

import { NgZone } from '@angular/core';
import { Router } from '@angular/router';

...
constructor(
    private employeeService: EmployeeService, 
    private router:Router,
    private ngZone: NgZone) { }

 onSubmit = function(user) {
   this.employeeService.addEmployee(user)
     .subscribe(
       (response) => { 
         this.ngZone.run(() =>
           this.router.navigate(['/employees']));
       }  
     );
}

Mali

1.import component which is to be navigated

eg. import { SampleComponent} from './Sample.component';

2.Add component to constuctor to be navigated

constructor( private Comp: SampleComponent){}

3.Add this code where u need to navigate

this.Comp.ngOnInit();
this._router.navigate(['/SampleComponent']);--/SampleComponent-your router path

eg.After employee Insert it redirects to employee list page

 this.service.postData(Obj)
          .subscribe(data => {
            (alert("Inserted Successfully"));
            this.Comp.ngOnInit();
            this._router.navigate(['/SampleComponent']);
          },
            error => {
              alert(error);
          });
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!