I am using angular2 routing. When the user re-enters the value in the search field and clicks on search, the same component needs to be reloaded but with different route parameters.
<button (click)="onReload()">Search</button>
onReload() {
this.router.navigate(['results',this.location]);
}
This is my route path for my ResultsComponent
{ path:'results/:location', component:ResultsComponent}
This function changes the URL, but it does not reinitialize the component.
In angularjs, ui-router I could achieve it like this.
$state.go($state.current, location, {reload: true});
How do I do this in angular4?
You need to perform the initialization logic within the subscription call back function within the subscription call back function of the route.params observable stream.
In your component class
@Component({
...
})
export class MyComponent implements OnInit {
myLocation:string;
constructor(private route:ActivatedRoute) {}
ngOnInit() {
this.route.params.subscribe((params:Params) => {
this.myLocation = params['location'];
// -- Initialization code --
this.doMyCustomInitialization();
}
}
private doMyCustomInitialization() {
console.log(`Reinitializing with new location value ${this.location}`);
}
}
On a different note, if you need to resolve data based on the value of 'location' you should use a resolve guard which resolves the data before the component is created. See https://angular.io/guide/router#resolve-guard for more information regarding resolve guards and routing.
Here's a working plunkr. https://plnkr.co/edit/g2tCnJ?p=preview
EDITED
The angular way of telling the router to do this is to use onSameUrlNavigation as of angular 5.1
But I had to solve this issue in a different way(Stackblitz), by subscribing
to route events
and actually calling a custom reInit method
.
The trick is to add all subscriptions to the same object and then unsubscribe ONLY when ngOnDestroy
is called by angular, and doing the rest of your template vars change from the custom destroy method
...
public subscribers: any = {};
constructor(private router: Router) {
/**
* This is important: Since this screen can be accessed from two menu options
* we need to tell angular to reload the component when this happens.
* It is important to filter the router events since router will emit many events,
* therefore calling reInitComponent many times wich we do not want.
*/
this.subscribers._router_subscription = this.router.events.filter(evt => evt instanceof NavigationEnd).subscribe((value) => {
this.reInitComponent();
});
}
reInitComponent() {
this.customOnDestroy();
this.customOnInit();
}
customOnInit() {
// add your subscriptions to subscribers.WHATEVERSUB here
// put your ngOnInit code here, and remove implementation and import
}
customOnDestroy() {
// here goes all logic to re initialize || modify the component vars
}
/**
* onDestroy will be called when router changes component, but not when changin parameters ;)
* it is importatn to unsubscribe here
*/
ngOnDestroy() {
for (let subscriberKey in this.subscribers) {
let subscriber = this.subscribers[subscriberKey];
if (subscriber instanceof Subscription) {
subscriber.unsubscribe();
}
}
}
Note that if you implement lifecylce hook ngOnInit, you should remove it and implement a custom method like in the example.
I added the unsubscription
method because of this angular bug. Angular should actually automatically unsubscribe from router.events when destroying the component, but since this is not the case, if you do not unsubscribe manually you will end up calling http requests(for example) as many times as you entered the component.
https://angular-2-training-book.rangle.io/handout/routing/routeparams.html
In your component you need to subscribe to the params in order to detect if they are changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With