Reputation: 893
I have created an application in angular 6 which upon login takes the user to the main page. This page contains multiple links on both the navbar at the top (called toolbar
) and the side bar on the left (called side-nav
). I have created a custom dynamic routing service that would add links and their labels for the html templates.
The paths are added to the router using router.config.unshift
, and I have verified that these paths are added properly under config
when I log the router in the console.
The login page of my application has the root path (i.e ' '
) and the Main
page after login has the path /main
(router configuration added below).
The problem I seem to be having has 2 parts:
whenever I click a link on the side-nav
or the toolbar
, the url on the address bar shows me localhost.com:4200/main/<path>
and the page displayed is the NotFoundComponent
(i.e it could not find the route). I don't want the path to be a child
of /main
but the root url (i.e ' '
), because the navigation bar would be on every page, and this might bring up a situation like localhost:4200/main/<path>/<anotherpath>/<someotherpath>/<path>
on clicking multiple items, which a is pretty bad design.
If i try to manually add the path to the application eg. localhost:4200/<path>
the same result is shown (NotFoundComponent
). No matter what I do it simply cannot find the path, even though in console it's perfectly defined when I log the router.
For testing purposes all my paths redirect me to a DummyComponent
.
Here is my code, I am sharing the code for my ToolbarComponent
, and the Side Nav is pretty much the same except for a few bits and pieces:
app.routing.ts:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from 'src/app/views/login/login.component';
import { MainComponent } from 'src/app/views/main/main.component';
import { AuthGuardService } from 'src/app/services/auth-guard/auth-guard.service';
import { NotFoundComponent } from 'src/app/views/error/not-found/not-found.component';
/**
* Contains a list of routes to enable navigation from one view to the next
* as users perform application tasks
* @property {array} routes
*/
export const routes: Routes = [
{
path: '',
component: LoginComponent,
},
{
path: 'main',
component: MainComponent,
canActivate: [AuthGuardService]
},
{
path: '**',
component: NotFoundComponent
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
dynamic-routing.service.ts
import { Injectable } from '@angular/core';
import { TranslatePipe } from 'src/app/pipes/translate/translate.pipe';
@Injectable({
providedIn: 'root'
})
/*
* This service will provide components with the ability to dynamically create
* routes within the application
*/
export class DynamicRoutingService {
/*
* Array for storing links
*
*/
private links = new Array<{ text: string, path: string, icon: string }>();
constructor(private translate: TranslatePipe) { }
/*
* Method to fetch data
*
*/
getLinks() {
if (this.links.length != 0) {
return this.links;
}
else {
throw new Error(this.translate.transform("generic[responses][error][404][002]"));
}
}
/*
* Method to store data
*
*/
addItem({ text, path, icon = null }) {
try {
this.links.push({ text: text, path: path, icon: icon });
} catch (e) {
throw new Error(this.translate.transform("generic[responses][error][400]"));
}
}
/*
* Method to remove a specific link
*
*/
removeItem({ text }) {
if (this.links.length != 0) {
this.links.forEach((link, index) => {
if (link.text === text) {
this.links.splice(index, 1);
}
});
} else {
throw new Error (this.translate.transform('generic[resposnes][error][404][002]'));
}
}
/*
* Remove all links from the array
*/
clearAll() {
this.links.length = 0;
}
}
toolbar.component.ts
import { Component, OnInit } from '@angular/core';
import { TranslatePipe } from 'src/app/pipes/translate/translate.pipe';
import { DynamicRoutingService } from 'src/app/services/dynamic-routing/dynamic-routing.service';
import { Router } from '@angular/router';
import { DummyComponent } from 'src/app/views/dummy/dummy.component';
@Component({
selector: 'app-toolbar',
templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.scss'],
providers: [DynamicRoutingService]
})
/**
* This component renders the Toolbar UI
*
*/
export class ToolbarComponent implements OnInit {
/**
* Object containing the translated names and their respective icons
* @property {array} links
*/
links: Array<{ text: string, path: string }>;
/**
* constructor for toolbar component is responsible for initializing translatePipe, dynamic routing and router,
* as well as adding routes dynamically to the router and the dynamicRouting service
* @param translate
* @param router
* @param dynamicRouting
*
*/
constructor(private translate: TranslatePipe, private router: Router, private dynamicRouting: DynamicRoutingService) {
this.router.config.unshift(
{ path: 'knowledge-base', component: DummyComponent },
{ path: 'home', component: DummyComponent },
{ path: 'settings', component: DummyComponent }
);
this.dynamicRouting.addItem({ text: "home", path: "home" });
this.dynamicRouting.addItem({ text: "knowledge_base", path: "knowledge-base" });
this.dynamicRouting.addItem({ text: "settings", path: "settings" });
}
/**
* Upon initialization this function fetches the links and inserts the translated
* text and path to be used by the template
*
* @param
* @return
*/
ngOnInit() {
this.links = [];
let rawData = this.dynamicRouting.getLinks();
let self = this;
rawData.forEach(function(data) {
let text = self.translate.transform("generic[toolbar][categories][" + data.text + "][label]");
self.links.push({ text: text, path: data.path });
});
}
}
toolbar.component.html
<app-header
[fixed]="true"
[navbarBrandFull]="{src: 'assets/logo.png', width: 143, height: 36, alt: 'RT Logo'}"
[navbarBrandMinimized]="{src: 'assets/logo2.png', width: 35, height: 35, alt: 'RT Logo'}"
[sidebarToggler]="'lg'">
<ul class="nav navbar-nav d-md-down-none" routerLinkActive="active">
<li class="nav-item px-3" *ngFor="let link of links">
<a class="nav-link" [routerLink]="link.path">{{ link.text }}</a>
</li>
</ul>
<ul class="nav navbar-nav ml-auto">
</ul>
</app-header>
Upvotes: 2
Views: 842
Reputation: 893
Solved: The problem lied in my template: the value passed to routerLink
needed to be modified, example here and solution here
Upvotes: 2