3

Currently I have three different modules:

  • App Module -- with emtpy an array Root configuration
  • Home Module -- with a '' path config for the homepage comp. for searching for a player
  • Player Result Module -- shows the result of the search (either player stats or error page)

Now in this player search module I have a player search result component with child components. One of the child component is a modal with a list in it. If i click on this list item (player) it should 'navigate' to the parent component and update its view. But the only thing that updates is the url.

There is a workaround with window.location.href(url) that relaods the page after the navigation method updates the url. But I don't like workarounds.

The parent component pretty much looks like:

export class PlayerSearchResultComponent implements OnInit, AfterViewInit {

 public isLoading = true;
  public searchValue: string;
  public playerResult: PlayerByPlayerTagType;
  public hasNoResultFound = false;
  public clanInfo: ClansByClantagType;

  constructor(private playerSearchService: PlayerSearchService,
              private activatedRoute: ActivatedRoute,
              private clanSearchService: ClanSearchService) {
  }

  ngOnInit(): void {
    this.activatedRoute.params.subscribe((params: Params) => {
      this.searchValue = params['playerId'];
    });
  }

  ngAfterViewInit() {
    this.playerSearchService.getPlayerByPlayerTag(this.searchValue).subscribe(player => {
        this.playerResult = player;
        if (!isUndefined(this.playerResult.clan)) {
          this.clanSearchService.getClanByClanTag(this.playerResult.clan.tag).subscribe((data: ClansByClantagType) => {
            this.clanInfo = data;
          });
        }
      }, () => {
        this.hasNoResultFound = true;
        this.isLoading = false;
      },
      () => this.isLoading = false);
  }
}

And the child component:

export class ClanModalComponent {

  @ViewChild('childModal') childModal: ModalDirective;
  @Input() playerResult: PlayerByPlayerTagType;
  @Input() clanInfo: ClansByClantagType;


  constructor(private router: Router) {
  }

  open() {
    this.childModal.show();
  }

  memberSearch(member) {
    this.childModal.hide();
    this.router.navigate(['search/' + member.tag]);
  }

}

The player result module looks like:

const appRoutes: Routes = [
  {path: 'search/:playerId', component: PlayerSearchResultComponent}
];

@NgModule({
  declarations: [
   ...
  ],
  imports: [
    ...
    RouterModule.forChild(
      appRoutes
    )],
  providers: [
     ...
  ],
  exports: []
})
export class PlayerResultModule {
}
2
  • what do you expect when changing the route? I guess the playerId changes? Commented Mar 25, 2018 at 15:36
  • When changing the route i expect that the parent component should be called and update the parent view. Commented Mar 25, 2018 at 15:37

2 Answers 2

6

So, to load based on the route param you have to subscribe to Route params and the load the data. The ngAfterViewInit will not be processed again. Because the component does not load again after route change!

ngOnInit(): void {
    this.activatedRoute.params.subscribe((params: Params) => {
        this.searchValue = params['playerId'];
        this.playerSearchService
            .getPlayerByPlayerTag(this.searchValue)
            .subscribe(player => {
                this.playerResult = player;
                ...
                ...
            });
     }
}
Sign up to request clarification or add additional context in comments.

2 Comments

holy cow! It works didnt expect that it would rely on that, but now i get a error thrown in the console this._subscribe is not a fuction
where do you call this._subscribe? I cannot see that anywhere.
0
//browser is already on /pathName/oldID, 
//this means our Routes are correct
 
 let newLocation = `/pathName/${newID}`;
 // override default re-use strategy
 this.router
    .routeReuseStrategy
    .shouldReuseRoute = function () {
        return false;
 };
 this.router
   .navigateByUrl(newLocation)
   .then(
   (worked) => {
        //works only because we hooked 
        //the routeReuseStrategy.shouldReuseRoute above
   },
   (error) => {
    debugger;
    }
 );

I've seen this issue more times than I care to admit, it usually is seen when I have a parent container reusing a child component.

  • Parent route is xyz/ by default. Everything loads fine.
  • Parent changes route to xyz/1 to show details of the person id of 1
  • The parent page does nothing but change the url.

This is because Angular's default route reuse strategy will not reload the page!

The code above fixes this default behavior but must be put into the proper component to get the reload from scratch behavior.

Note there are alternatives... Assume you want to maintain the speed of component reuse. In that case just provide an entry point into the already loaded component that resets the data, leaving the component to change via changeDetectorRef.DetectChanges().

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.