8

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?

2
  • we have the same problem :( Commented Aug 3, 2017 at 11:17
  • @vistajess Do tell me if you find a solution. Commented Aug 3, 2017 at 12:20

3 Answers 3

4

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

Sign up to request clarification or add additional context in comments.

8 Comments

I am subscribing to the params. My URL also changes to the new params. But the component doesn't reinitialize.
You need to perform the initialization logic that is based on the location value within the subscribe call back function. This way, whenever the route changes (and hence params), the initialization logic is reexecuted. For efficiency, angular does not destroy and recreate a component if the route navigated to is bound to the same component.
I tried putting the initialization logic inside the subscribe call back. It still doesn't work. Also my initialization logic is a call to a http service to which I am passing the location and obtaining the data.
In your case you need to use a resolve guard, which can use the location value. See the link i've posted in the answer above.
Guards are used to stop the routing until your asynchronous tasks are finished. In my case, the asynchronous task needs to be done after route has changed. So, I don't know how Resolve Guard can help me with this.
|
3

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.

1 Comment

In simple "use onSameUrlNavigation" this is the solution @CKA if this works pl. mark it as correct answer.
2

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.

2 Comments

I am subscribing to the params. My URL also changes to the new params. But the component doesn't reinitialize
Thanks for the info. I forgot to subscribe params in constructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.