Reload Angular 4+ route with the same URL parameter
Asked Answered
G

7

10

I've been doing some research into reloading an Angular 4+ route and it looks as if the preferred method is to instead listen to URL parameter changes within the component and re-initialise the component there instead.

The issue I'm having is in trying to find a DRY (don't repeat yourself) approach to make this work across multiple components, when the URL would be identical (including parameters). In AngularJS this was simple with UI-router.

Use case:

I have a notification panel which can "float" above any route, when a notification is clicked it needs to go to the content it relates to - this can be many different types of content.

For example: /posts/:id or /groups/:id or /users/:id

If the user is already looking at that content it doesn't reload and refresh to reflect the message of the notification. I.e "John Doe commented on your post" (the user could be looking at an outdated version of that post) or "Jane Doe accepted your request to join Some Group" (the user could be looking at the guest view of that group).

I did look into using window.location.reload() when detecting that the route is the same, and that works, but it's highly undesirable due to the overhead it causes (angular reinitialising, auth check, socket reconnection, etc).

Any suggestions would be greatly appreciated!

Generator answered 9/10, 2017 at 12:7 Comment(1)
Have you looked at the Router's onSameUrlNavigation setting? Default is ignore but there's a reload option as well. I don't have experience with it, though.Gregoor
D
2

In this case your route doesn't change, just your parameters change.

To solve this problem you need to subscribe to the ActivatedRoute params.

export class MyClass implements OnInit {
   constructor(private activatedRoute: ActivatedRoute ) {
        this.activatedRoute.params.subscribe((params)=>{
          console.log('updatedParams', params);
        });
    }
}
Douty answered 8/12, 2017 at 11:18 Comment(0)
E
1

You have to subscribe route params so that whenever it changes we can handle changes. Below is sample code from my project which is working perfectly fine.

constructor(private router: Router) {
    this.route.params.subscribe(params => {
      this.initializePage(params['id']);
    });
}

initializePage(id:any){
//..Your code
// Consider this as your ngOnInIt() method and initialize everything here.
}

Here when param value changes in URL with same route it will not reload page but just change value as we are calling initializePage(id) which will re initialize everything.

Hope this help you.

Edieedification answered 19/10, 2018 at 10:8 Comment(0)
H
0

There is no way to just re-load the route when nothing has changed in the URL. Indeed, the only options you have are window.location.reload() and listening to the parameters change.

For the second option, you can create a generic service that will watch the changes of the id argument in query string. Let's call it IdWatchService and it would look something like this:

@Injectable()
export class IdWatchService {
  constructor(private route: ActivatedRoute) {
  }

  get idChange(): Observable<number | undefined> {
    return this.route.queryParams.map(p => p['id'] as number | undefined).distinctUntilChanged();
  }
}

Then you can add this service to the list of providers on the components that need to react to the changes (PostsComponent, GroupsComponent, etc.). And finally, you can inject it to the those same components and subscribe to the idChange observable:

@Component({
  templateUrl: './posts.component.html',
  providers: [
    IdWatchService
  ]
})
export class PostsComponent {
  constructor(idWatchService: IdWatchService) {
    idWatchService.idChange.subscribe(id => {
      // Load data for the new ID and refresh the view
    });
  }
}
Harelip answered 9/10, 2017 at 12:24 Comment(2)
I think this is not what has been asked. Citation from the question > when the URL would be identical (including parameters)Seamstress
@Seamstress Indeed, I see. However there is no way to do this without window.location.reload(). I modified my answer a little to make this clear.Harelip
S
0

I faced the same scenario (very similiar use case) back in angular 2. Like other answers said, I found there was no built in way in angular to do this (maybe the framework assumption is that such case should be solved just by listenning for changes in the params).

Like you, I didn't want to rewrite my code, so I used a different solution, its a bit more hacky, but it worked without much need for change.

The solution I used was creating a dummy route under the same level of hirearchy where you need to reload the page. The in the dummy route I used a DummyComponent that receives in the route params data that describes what was the next route we need to go to (the one that we want to reload) and which params should I pass to it (such as id you have mentioned) and then I used the injected Rounter class with the navigate method to go to that route.

I think this solution will be much more efficient than using window.reload and its pretty simple to write. (I can't copy that code example because I don't have access to that code)

Soupspoon answered 6/11, 2017 at 12:3 Comment(0)
A
0

I was facing the same problem with the notification section in the header I have solved this problem with DoCheck

import { Component, DoCheck } from '@angular/core';

In Class implement the DoCheck interface

export class HeaderComponent implements DoCheck {

Then use ngDoCheck() method and verify if the variable value changes it will show the same in your notification area

ngDoCheck() {
    // check if values changes
}
Ant answered 5/1, 2018 at 13:15 Comment(0)
I
0

By this.router.url you will get url of current page. Than use router navigation as with queryParames. following is the example of passing queryParams as page for pagination. You can use similar approch.

const url = this.router.url.split('?')[0]; // this will remove previous queryparms
    this.router.navigate([url], { queryParams: { page: $event } });
Incorporation answered 3/3, 2018 at 8:53 Comment(0)
C
-3

window.location.reload();

That's work for me.

Chivy answered 6/11, 2017 at 12:51 Comment(1)
this will refresh the entire pageMaramarabel

© 2022 - 2024 — McMap. All rights reserved.