1

I develop a MEAN stack application and for the Front-End I use Angular. In angular, I use a navbar and a sidenav bar which are the framework of my layout. Then the routes are displayed in the mat-sidenav-content -> ng-content here:

FRAMEWORK COMPONENT HTML

  <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    MY CONTENT NAVBAR
  </nav>

  <mat-sidenav-container class="sidenav-container">
    <mat-sidenav>
    MY CONTENT SIDENAV
    </mat-sidenav>

    <mat-sidenav-content style="background-color: #ecf0f1">
      <ng-content></ng-content>
    </mat-sidenav-content>
  </mat-sidenav-container>
</div>

The others components are displayed properly. However, I would like to access the url from the framework component like this:

       import { ActivatedRoute } from "@angular/router";
[...]
        constructor(private route: ActivatedRoute) {}
[...]
        this.route.snapshot.params["id"]

It doesn't work because it's undefined whereas if I do it in the other components it works. I think it is because the FRAMEWORK component is not defined in the router therefore there is not URL for this component.

I tried to use a sharing data service. Like this I set the id value in the other component and the framework component can use it. But it doesn't work because Framework component is loaded before the other component.

PierBJX
  • 2,093
  • 5
  • 19
  • 50
  • Have you tried using `Subject` to emit the `id` from Service, so that `framework` component will be subscribing to it and receives the value upon emitting. – Amit Chigadani Jul 15 '18 at 10:23
  • And you will not be able to access `id` via `ActivatedRoute` in `framework` component. Because that is not the component which gets loaded on a route change. Service would be better option. – Amit Chigadani Jul 15 '18 at 10:27
  • Yes, I used a BehaviorSubject. The problem was that if I was writing directly in the URL the route, the id was not updated. I needed to reload the page again. Because the only solution to update it was in the other components – PierBJX Jul 15 '18 at 10:27
  • Why do you need to reload the page, after changing the `id` in the url, just hit `return (Enter)`. It should load the component and call service method to emit the id. – Amit Chigadani Jul 15 '18 at 10:32
  • In fact, if I change the id in the URL the routes components displayed the proper data but the main nav does not know the id which is undefined. Because the main nav is loaded before the routes components – PierBJX Jul 15 '18 at 10:41
  • Your comment seems confusing to me. Which component gets loaded on route change? And which component requires the id from the url? – Amit Chigadani Jul 15 '18 at 10:46
  • The main nav needs the id from the URL. After I have several components on route change but all of them can get the ID from the URL. The first page is home page but there is not need of the ID. Then I click on a button to go to my route components. By clicking on the button it updates the shared variable "id" and the main nav is updates. However, when I change the ID manually in the URL address, the id is undefined because usually it is the button which update the shared variable – PierBJX Jul 15 '18 at 11:00
  • In that case, you may subscribe to route change events in the component that gets loaded. And then update the `id` of service from there. So that main `nav` will receive the updated id after it is emitted from service. – Amit Chigadani Jul 15 '18 at 11:05
  • Yes I did it also but when the variable is updated I can see it in the console browser that the value changed but the component is not updated – PierBJX Jul 15 '18 at 11:42
  • Your service is probably not a singleton then. I have made an answer check that. – Amit Chigadani Jul 15 '18 at 12:55

2 Answers2

1

You may subscribe to route change events in the component that gets loaded. And then update the id of service from there. So that main nav component will receive the updated id after it is emitted from service.

And you should make your service singleton, so that each component share the same Service instance. To do this, you should provide your service at the module level.

shared service

class Service {
   emitData(id){
      this.sub.next(id)
   }
}

Nav comp

class NavComponent {
       ngOnInit(){
          this.service.sub.subscribe(id => console.log(id));
       }
}

Routed comp

class NavComponent {
       ngOnInit(){
        this.router.events.subscribe((event) =>
        {
          if(event instanceOf NavigationEnd) { 
             // fetch id from url and call service method to emit data
              this.service.emitData(id);
          }
       });
 }
Amit Chigadani
  • 28,482
  • 13
  • 80
  • 98
0

I would just pass the id through property to the nested component instead all of this .. but if you explicitly need to get the param by using ActivatedRoute you can do something like this :

on your app-routing.module you can specify the nested component in the 'children' array of the component of which it is nested .

const routes: Routes = [
  ...
  {
    path: 'somepath/:id',
    component: SuperComponent,
    children: [
      {path: '', redirectTo: ''}, 
      {path: 'tailpath', component: NestedComponent}, 
    ]
  },
  ... 
];

on your template

< nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    MY CONTENT NAVBAR
</nav>
...
<router-outlet></router-outlet>
...

the nested component will render on the router-outlet element and in it you coulde use ActivatedRoute and fetch the id param.

for further information go here

Ofir G
  • 736
  • 6
  • 18
  • This won't work because I need the id in the main nav and with that the id will be accessible from the router-outler and I need it in the nav – PierBJX Jul 15 '18 at 11:29
  • are you 100% sure of what you're saying ? the id param should be accessible through both of the component, they both render under the same path. – Ofir G Jul 15 '18 at 11:42
  • With children path the main nav won't be in the router path. So it won't have access to the id – PierBJX Jul 15 '18 at 11:45
  • Because I have this path: http://localhost:4200/home or http://localhost:4200/experiment/:id or http://localhost:4200/signin. In each case there is the nav bar and the id is not defined for all of them – PierBJX Jul 15 '18 at 11:48