In Angular2, Use Service to get application routes - angular6

I have angular 6 application. I have requirements to get dynamic routes, logic of which is been sorted. I have AppRoutingService class which has method getAppRoutes() returning static route collection. I need this to be called app RouterModule.forRoot(...), the objective if can manage to inject static routes using service class, then I can assemble dynamic routes from database in this static list.
In doing so I am getting error.
error
Uncaught TypeError: Cannot read property 'appRoutingService' of undefined
at main.js:1055
at Module../src/app/modules/application/app-routing.module.ts (main.js:1065)
at __webpack_require__ (runtime.js:84)
App routing class
import { AppRoutingService } from './services/routing/app-routing-service';
#NgModule({
imports: [
RouterModule.forRoot(this.appRoutingService.getAppRoutes()) // here i need to inject appRoutingService method... need help here....???
],
exports: [
RouterModule
]
})
export class AppRoutingModule {
constructor(
private router:Router,
private appRoutingService: AppRoutingService
) {
}
}
App Routing Service class
#Injectable()
export class AppRoutingService{
public RouteCollection: Routes = [
{
path:'',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: '',
component: WebLayoutComponent,
children:[
{
path:'dashboard',
loadChildren: '../dashboard/dashboard.module#DashboardModule'
},
{
path:'survey',
loadChildren: '../survey/survey.module#SurveyModule'
}
]
},
{
path:'**',
component:PageNotFoundComponent
}
];
public getAppRoutes(): Route[]
{
return this.RouteCollection;
}
}

You are using the keyword "this" in a wrong place. there is no "this" in that context, because it is outside of a class. Since "this" === undefined, then the reason behind the error becomes clear, because you are trying to fetch the appRoutingService from undefined.
#NgModule({
imports: [
RouterModule.forRoot(AppRoutingService.getAppRoutes()) // here i need
to inject appRoutingService method... need help here....???
],
exports: [
RouterModule
]
})
And make the AppRoutingService method and variable static.
public static RouteCollection: Routes = [
{
path:'',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: '',
component: WebLayoutComponent,
children:[
{
path:'dashboard',
loadChildren: '../dashboard/dashboard.module#DashboardModule'
},
{
path:'survey',
loadChildren: '../survey/survey.module#SurveyModule'
}
]
},
{
path:'**',
component:PageNotFoundComponent
}
];
public static getAppRoutes(): Route[]
{
return AppRoutingService.RouteCollection;
}

Related

How to pass additional route parameter in angular?

I am working on Angular 6 application and have route survey that is config on app root level and then :id to take it survey detail page, I am trying to navigate from component using
this.router.navigate(['/survey'], this.listedSurvey.surveyIdNum);
But I believe I am missing something from router navigate as I am unable to do so.
App route
const routes: Routes = [
{ path:'welcome', component:WelcomeComponent },
{ path:'', redirectTo: 'welcome', pathMatch:'full'},
{ path:'survey', loadChildren: '../survey/survey.module#SurveyModule' },
{ path:'**', component:PageNotFoundComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
survey module
const routes: Routes = [
{
path:'',
component:SurveyComponent,
},
{
path:':id',
component: SurveyFormComponent
}
];
#NgModule({
imports:[
RouterModule.forChild(routes)
],
exports:[]
})
export class SurveyRouting{
}
component
private handleSelectedSurvey(dataItem:any){
this.listedSurvey = dataItem;
const a:number = 2;
//this.router.navigate(['/survey'], this.listedSurvey.surveyIdNum);
this.router.navigate(['/survey'],{queryParams:{id:a}});
}
Change the navigate()
this.router.navigate(['/survey', this.listedSurvey.surveyIdNum]);
Refer: https://angular.io/api/router/Router#navigate

How to import Routes in the Spec

I have the following route defined in app-routes.ts as a separate module
import {NgModule} from '#angular/core';
import {RouterModule, Routes} from "#angular/router";
import {AppComponent} from "./app.component";
...
const routes:Routes = [
{
path: 'new',
component: New
canActivate:[AuthGuard]
},
{
path:'list',
component:List
},
{
path: 'signup',
component: SignupComponentComponent
},
{
path: '',
redirectTo: 'home',
pathMatch:'full'
},
{
path: 'home',
component:HomepageContentComponentComponent
},
{ path: '**',
component: PageNotFoundComponent }
];
#NgModule({
imports:[RouterModule.forRoot(routes)], //
exports: [RouterModule],
providers:[]
})
export class AppRoutingModule{}
I am using the route in the HomePageComponent. How do I test the routing? I know I need to use RouterTestingModule. like follows:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports:[RouterTestingModule.withRoutes(routes)], //routes is undefined here
declarations: [ HomepageContentComponentComponent,
]
})
.compileComponents();
}));
But the routes variable defined as const routes:Routes = ... in AppRoutingModule isn't available here.
Question 1) How in my current setup, I can make routes visible in the specs
Question 2)I thought to create a separate file myroutes.ts which contains only the routes array so that I can use it in the specs but even that doesn't work. Why? ( something like the following)
my-route.ts
const routes:Routes = [
{... ];
Why am I note able to use routes in imports:[RouterTestingModule.withRoutes(routes)] when I created it in a sepafrate file?
I should have exported the routes as export const routes:Routes

After guard implementation, the unauthorized url return to main screen not showing data

When I run the angular app, it redirects to localhost:4200/events page where I have data to be displayed. Now I have implemented guard service as beforelogin & afterlogin to let allow user to access the certain page before and after login.
Example: if the user is not logged-in and if the user hits url "localhost:4200/special" directly I want it redirect to localhost:4200/events page but instead it redirect to localhost:4200 page. I have tried to display data to this localhost:4200 page as well but data is not being displayed.
Instead of
path:'', redirectTo: 'events',
I have also tried:
path:'', component: EventComponent
app-routing.module.ts
import { BeforeLoginGuard } from './guards/before-login.guard';
import { AfterLoginGuard } from './guards/after-login.guard';
const routes: Routes = [
{
path:'',
redirectTo: 'events',
pathMatch: 'full'
},
{
path: 'login',
component: LoginComponent,
canActivate: [BeforeLoginGuard]
},
{
path: 'signup',
component: SignupComponent,
canActivate: [BeforeLoginGuard]
}
{
path: 'events',
component: EventsComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
after-login.guard
export class AfterLoginGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this._tokenService.loggedIn();
}
constructor(private _tokenService: TokenService) { }
}
events.component
export class EventsComponent implements OnInit {
events = [];
constructor(private _eventService: EventService) { }
ngOnInit() {
this._eventService.getEvents()
.subscribe(
res => this.events = res,
err => console.log(err)
);
}
}

How to nest more than 1 level route in Angular route?

i make an dashboard app for manage data using angular 6. but i stuck when i nest more than 1 lazyload route, it's not work, It's seem like can not add more than 1 lazyload route in angular router
My App routing :
const appRoutes: Routes = [
{
path: '',
component: SigninComponent,
pathMatch: 'full'
},
{
path: 'dashboard',
loadChildren: './core/dashboard/dashboard.module#DashboardModule'
}
];
#NgModule({
imports: [
RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
my dashboard route
const dashboardRoutes: Routes = [
{
path: '',
component: DashboardComponent,
children: [
{
path: 'products',
pathMatch: 'full',
loadChildren: './products/products.module#ProductModule'
},
]
}
];
#NgModule({
imports: [RouterModule.forChild(dashboardRoutes)],
exports: [RouterModule]
})
My product route:
const productRoutes: Routes = [
{
path: '',
component: ProductListComponent,
children: [
{
path: ':id',
component: ProductEditComponent
},
{
path: 'addproduct',
component: ProductCreateComponent
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(productRoutes)],
exports: [RouterModule]
})
when i access localhost:4200/dashboard/products/id3 it take an error: can not match any route 'dashboard/products/id3'. I think i wrong some where in routing setup but i cant not find where is an error. Anyone can help me ?
I've create a page for you..Just check and do the changes accordingly. You need to check module path correctly otherwise it should work with no issue. You can change the url to hello.
https://stackblitz.com/edit/angular-lazy-loading-nweyjt
// For eg.
// https://stackblitz.com/edit/angular-lazy-loading-nweyjt/hello/3

Routing in Angular 4

I have an issue with routing in my app. In my local all works right but not on the server. The program has the following routes:
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'thankyou', component: ThankyouComponent },
{ path: 'home', component: UserHomeComponent, canActivate: [AuthGuard] },
{ path: 'publish', component: PublishComponent, canActivate: [AuthGuard] },
{ path: '**', component: PageNotFoundComponent }
];
The root route always works.
If on my computer I send request directly, for example, the route:
http://localhost:4200/publish
Assuming that I have logged in there are no problems loading it. But if execute that route in server with the route:
http://myserver/mypath/dist/publish
It doesn't find the route.
I modified index.html as well, to execute on server.
<base href="/"> by <base href="/mypath/dist/">
If I execute that route by the template html using directive
routerLink="/publish"
It works fine.
Does anyone know why this happens?
Your webserver needs to be configured to reroute requests to your index.html, excluding assets.
For nginx, add this inside your server block of your nginx.conf or your site config:
location / {
try_files $uri $uri/ /path/to/index.html;
}
For apache, check this answer.
Here is an example of a file that creates a routing structure for the routes to hit when they are put into the url. So far I have not seen anything in your question that suggests you are actually handling routes from outside your app. In other words, how does some url from your server know where to go if you haven't defined a route that would be typed in as a url? Seems you don't have a root path. That's what I've been driving at.
import { Routes, RouterModule } from '#angular/router';
import { SomeComponent } from 'app/components/some-component';
import { Path1Component } from 'app/components/path1-component';
import { Path2Component } from 'app/components/path2-component';
import { Path3Component } from 'app/components/path3-component';
const MyRoutes: Routes = [
{
path: 'root/',
component: SomeComponent,
children: [
{
path: 'path1',
component: Path1Component
},
{
path: 'path2',
component: Path2Component
},
{
path: 'path3',
component: Path3Component
},
{
path: '**', // default path
component: Path2Component
}
],
}
];
#NgModule({
imports: [
RouterModule.forChild(MyRoutes)
],
exports: [
RouterModule
]
})
export class MyRouting { }
I have found the solution in this site https://github.com/angular/angular/issues/11884
but I don't have full access to server. I have switched in root module to HashLocationStrategy as the angular guide says here https://angular.io/guide/router#appendix-locationstrategy-and-browser-url-styles
and it works!