0

I would like for the links on my sidebar to be dynamically generated based on the page URL / various service data.

That is to say: If I am on a property page ~/meters/meter/54321, I would like to click on a link on the sidebar that will send me to ~/meters/meter/54321/overview.

(Bonus points: If I am not on a property page, I would like the option not to show up on the sidebar, but first things first.)

Note that I have two different ways to be getting the id - either through a MeterService or via the paramMap.

When I'm doing this on a normal component/routing module, /meters/meter/:id/overview resolves perfectly to /meters/meter/54321/overview, and I'm able to create a simple routerlink from the page.

The issue is that :id is not resolving to the paramMap id, rather, it is trying to send me to /meters/meter/:id/overview.

Is there something special about a sidebar that makes this work differently? Should I be importing something else?

Thank you!

component.ts:

import { Component, OnInit} from '@angular/core';
import { Routes, RouterModule, ActivatedRoute } from '@angular/router';
import { MeterService } from "../../shared/services/meter.service";

declare interface RouteInfo {
    path: string;
    title: string;
}
export const ROUTES: RouteInfo[] = [
    { path: '/meters', title: 'Property List' },
    { path: '/meters/add', title: 'Add Property'},
    { path: '/meters/meter/:id/overview', title: 'Property Overview'},
];

@Component({
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {
  menuItems: any[];
  meter: string;
  id: string;

  constructor(private meterService: MeterService, private route: ActivatedRoute) {
  this.id = this.route.snapshot.paramMap.get('id'); 
}

  ngOnInit() {
    this.meterService.currentMeter.subscribe(meter => {this.meter = meter; this.menuItems = ROUTES.filter(menuItem => menuItem);})
  }

component.html:

<ul class="nav">
        <li routerLinkActive="active" *ngFor="let menuItem of menuItems" class="{{menuItem.class}} nav-item">
            <a class="nav-link" [routerLink]="[menuItem.path]">
                <p>{{menuItem.title}}</p>
            </a>
        </li>
    </ul>
Ezra Butler
  • 120
  • 2
  • 13

1 Answers1

1

First, let's assuming we are on page ~/meters/meter/54321, we can navigate to ~/meters/meter/54321/overview with

<a class="nav-link" routerLink="./overview">
            ...
</a>

or

routerLink="overview"

or even

[routerLink]="['overview']"

We know how to navigate to a child route. But how to display this tag only on a specific page ? The core of the solution can be found here https://stackoverflow.com/a/45260402.

The idea is to listen to router events in your sidebar component and for each route change, hide or display the (with for example an NgIf directive).

serrulien
  • 695
  • 4
  • 14
  • This is actually interesting: for some reason when I do that (and I had tried it before), clicking from the sidebar sends me to `/meters/overview`, and I'm trying to now figure out why it's not treating `/meters/meter/54321` as the current page. – Ezra Butler Feb 03 '20 at 20:36
  • It seems like it was a routing issue. Thank you! – Ezra Butler Feb 03 '20 at 20:45
  • 1
    Fine, note also that i've give you some hints to handle your 'bonus point' ;) – serrulien Feb 03 '20 at 20:50