0

Initially my page loads data by the route. So normally the route is localhoat:8000\bProject.

On the page there is a drop down menu, when I select the value I want the url changed by the value. It should be liking localhost:8000\CaseId\5.

The Route code.

const routes: Routes = [
  {path: 'bProject', component: BProjectComponent},
  {path: 'bProject/CaseId/:id, component: BProjectComponent}
];

The drop down select value method is

private loadCaseData() {
  const url = 'app/bProject/CaseId';
  this.router.navigate([url, this.caseId]);
}

The code did work, however I found that the ngOnInit was called twice. I doubt that there were two component instance running because in the routes, I use the same component twice.

Is it right to use navigation?

C.OG
  • 6,236
  • 3
  • 20
  • 38
Hello
  • 796
  • 8
  • 30
  • I don't think it makes sense for ngOnInit() to be cancelled as that is part of the Angular lifecycle hooks. A problem with your routes is that you should have your 2nd route as the child of the 1st one. – Antediluvian Oct 29 '19 at 23:37
  • I don't follow you. Please explain it. – Hello Oct 29 '19 at 23:41
  • `I doubt that there were two component instance running...`. Your observations would suggest this is incorrect. There is most certainly two instances of the component, one for each route. When you change routes the first is destroyed and a new instance is initialized. – MS_AU Oct 29 '19 at 23:45
  • Okay, then how to fix it? – Hello Oct 29 '19 at 23:47
  • How are you so confident that `ngOnInit` is calling twice? any clue? – Pardeep Jain Oct 29 '19 at 23:59
  • I set a break point in ngOnInit and found the fact. – Hello Oct 30 '19 at 00:00

2 Answers2

0

The problem is that you are reloading twice the same Component: BProjectComponent.

First: when you load the Project Component.

Second: After you pick an element in the select, you navigate to a route that takes you to the same Component with an added path.

I recommend you that CaseId be a Children of the '/bProject' path.

const routes: Routes = [
  {path: 'bProject', component: BProjectComponent, children: [
    {path: 'CaseId/:id, component: CaseComponent}
  ]}
];

Then you drop down select value method should be:

private loadCaseData() {
  this.router.navigate([./CaseId, this.caseId]);
}
German Quinteros
  • 1,870
  • 9
  • 33
  • The question is if I do it in child component way. There are so many duplicate code. Should I create new component? A lot of work. The web interface are same for the navigation. The difference is just the values in controls. – Hello Oct 30 '19 at 00:03
  • There shouldn't be duplicate code. At the moment that you navigate to a child route the parent is the same and he didn't reload, it will only load the child element inside the . – German Quinteros Oct 30 '19 at 00:07
  • I meant should I rewrite the html for child component? They are same and a lot of code. Can I just let it does the dirty work, call twice, fine. Added some logic to avoid any loading delay? – Hello Oct 30 '19 at 00:15
  • If the caseId selected it's so important but you don't need it on the route, you can save it in a BehaviorSubject. On the other hand, if you need the caseId in the route yes, you should do a refactor. Probably you can avoid the refactor and do some dirty work but bad code it's worst to maintain. – German Quinteros Oct 30 '19 at 00:23
  • Can we use query parameters instead of because I am not familiar with BehaviorSubject? – Hello Oct 30 '19 at 11:50
  • BehaviorSubject are really easy to use. Here you have some examples: [https://www.learnrxjs.io/subjects/behaviorsubject.html], [https://stackoverflow.com/questions/39494058/behaviorsubject-vs-observable], [https://medium.com/@luukgruijs/understanding-rxjs-behaviorsubject-replaysubject-and-asyncsubject-8cc061f1cfc0] – German Quinteros Oct 30 '19 at 19:57
0

It turns out I created a global service to store data.When the second instance comes out I retrieve the data from the service instead of reloading it from the database.

It sounds dirty but I have to do that.

Hello
  • 796
  • 8
  • 30