Application routing overrides modules routing - javascript

I've met some interesting situation while developing application using Angular 4.1.1. I've always declared routing in a module and I do it in all modules.
For example, new-cars.routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { NewCarsComponent} from './new-cars.component';
import { NewCarsResolver } from './new-cars.resolver';
#NgModule({
imports: [
RouterModule.forChild([
{
path: 'cars/:id',
component: NewCarsComponent,
resolve: {
card: NewCarsResolver
}
}
])
],
exports: [RouterModule]
})
export class NewCarsRoutingModule { }
Then I've read this article to redirect to "404 Not Found" component, if user inputs not exisiting URL address. And I declared this route in app-routing.module.ts:
export const routes: Routes = [
{ path: '**', component: PageNotFoundComponent }
];
and now all pages show Page not found.
app.module.ts:
import ...;
import { NewCarsModule } from './new-cars/new-cars.module';
import ...;
#NgModule({
imports: [
RouterModule,
BrowserModule,
AppRoutingModule,
HomeModule,
SearchModule,
CoreModule,
NewsCarsModule,
],
declarations: [
AppComponent,
PageNotFoundComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
My questions is Is it possible to write { path: '**', component: PageNotFoundComponent } just in one place, not in all components?

The main problem here is the order of your routes.
#NgModule({
imports: [
...
NewsCarsModule, // this order is important
AppRoutingModule // where you declared PageNotFoundComponent
],
...
})
export class AppModule {}
See also
https://github.com/angular/angular/issues/12648

Related

Regarding not loading component in order Angular with Lazyload Routing

I am using lazyload routing in our application! I'm facing strange issue as follows
I have AppModule in side that TopModule and then DashboardModule and all are loaded in lazyload
if someone open localhost:4200/dashboard then it loads in order of Appmodule,Topmodule DashboardModule and TopComponent
but it should loads in order of Appmodule,Topmodule,TopComponent and DashboardModule
As Dashboard Module is getting loaded Before TopComponent because of it my page is getting stucked!
NOTE : I have used in all modules where routing are defined!
My code is as follows
app.module.ts
import { CommonModule } from '#angular/common';
import { NgModule } from '#angular/core';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { RouterModule, Routes} from '#angular/router';
import { AppComponent } from './app.component';
import { BrowserModule } from "#angular/platform-browser";
const appRoutes: Routes = [
{
path: '',
loadChildren: './top.module#TopModule',
}
];
#NgModule({
declarations: [
AppComponent
],
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot(appRoutes)
],
providers: [],
entryComponents: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
app.component.html
<router-outlet></router-outlet>
top.module.ts
import { CommonModule } from '#angular/common';
import { NgModule } from '#angular/core';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { RouterModule, Routes} from '#angular/router';
import { TopComponent } from './top.component';
import { BrowserModule } from "#angular/platform-browser";
const appRoutes: Routes = [
{
path: '',
component: TopComponent,
children: [
{
path: '',
loadChildren: './first.module#FirstModule',
},
{
path: 'dashboard',
loadChildren: './dashboard.module#DashboardModule',
},
]
}
]
#NgModule({
declarations: [
TopComponent
],
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
RouterModule.forChild(appRoutes)
],
providers: [],
entryComponents: [],
})
export class TopModule {
}
top.component.html
<router-outlet></router-outlet>
First of all, as you stated in comment above, if TopComponent should appear in all view, it doesn't make sense to load it lazyly. You should add TopModule to your AppModule because users will get it no matter the url they enter.
Next, to load FirstModule and DashboardModule lazyly you can do it as below:
const appRoutes: Routes = [
{
path: '',
component: OutletComponent,
children: [
{
path: '',
loadChildren: './first.module#FirstModule',
},
{
path: 'dashboard',
loadChildren: './dashboard.module#DashboardModule',
},
]
}]
And finally create a component for childrens routing:
//OutletComponent
#Component({
selector: 'outlet-component',
template: `<router-outlet></router-outlet>`,
})
export class OutletComponent {}

Navigation change url, but not view

I have an angular application with a login component
this component is under app/main/login
I want to go to it from app.component.html via the button
Here is my app-routing.module code
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { LoginComponent } from './main/login/login.component';
const routes: Routes = [
{ path: 'main', children: [{ path: 'login', component: LoginComponent }] },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
Here is how I try to use route <button mat-raised-button class="btn-default" [routerLink]="['/main/login']">Log in</button>
Here is app.module.ts code
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {MatButtonModule} from '#angular/material/button';
import {MainModule} from './main/main.module'
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MatButtonModule,
MainModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
and here is main.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { LoginComponent } from './login/login.component';
#NgModule({
declarations: [LoginComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [],
})
export class MainModule {}
When I click the button, the URL changing to http://localhost:4200/main/login but the view not changed.
How I can fix this?
Looking at your code it seems that you are trying to load component using lazy-loading technique.
So in AppRoutingComponent.ts file, instead of what your code replace it with :
const routes: Routes = [
{ path: 'main', loadChildren: '(path to main module)/main.module#MainModule' },
];
In layman terms this just tells the parent routing module to load the main.module when main path is encountered
Now In Main.module, configure child routes as:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { LoginComponent } from './login/login.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent }
];
#NgModule({
declarations: [LoginComponent],
imports: [
BrowserModule,
RouterModule.forChild(routes) // Register routes for child module via forChild function instead of for Root
],
providers: [],
bootstrap: [],
})
export class MainModule {}

Uncaught (in promise): Error: Cannot match any routes (Angular8)

I maked my angular-app. All good works. But for deploy to server I getting error:
Uncaught (in promise): Error: Cannot match any routes. URL Segment:
'myUrl/app.aspx'
After build prod my app doesn't work either (I set base href and all files load, but I getting warning Unhandled Navigation Error).
I make difficult routing for my app.
I using submodules for routing. And I think the problem related with APP_BASE_HREF or wrong routing for my app/submodules.
My example:
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from "#angular/common/http";
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { NbThemeModule, NbLayoutModule, NbSidebarModule, NbButtonModule, NbTabsetModule, NbCardModule } from '#nebular/theme';
import { NbEvaIconsModule } from '#nebular/eva-icons';
import { AppRoutingModule } from './app-routing.module';
import { RouterModule } from '#angular/router';
import { MainModule } from './components/main/main.module';
import { AddModule } from './components/add/add.module';
import { APP_BASE_HREF } from '#angular/common';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
NbThemeModule.forRoot({ name: 'default' }),
NbLayoutModule,
NbEvaIconsModule,
NbSidebarModule.forRoot(),
NbButtonModule,
NbTabsetModule,
NbCardModule,
AppRoutingModule,
MainModule,
AddModule,
HttpClientModule,
],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }],
bootstrap: [AppComponent]
})
export class AppModule { }
I don't have providers: [{ provide: APP_BASE_HREF, useValue: '/' }] and all good works. But for deploy I geted error message:
Please provide a value for the APP_BASE_HREF token or add a base
element to the document.
I add APP_BASE_HREF and error disappeared.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{
path: '',
loadChildren: './components/main/main.module#MainModule'
},
{
path: 'event',
loadChildren: './components/event/event.module#EventModule'
},
{
path: 'add',
loadChildren: './components/add/add.module#AddModule'
},
{
path: 'archive',
loadChildren: './components/archive/archive.module#ArchiveModule'
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
main-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ViewEventsComponent } from './view-events/view-events.component';
const routes: Routes = [
{
path: '',
component: ViewEventsComponent,
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class MainRoutingModule { }
event-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { EventPageComponent } from './event-page/event-page.component';
const routes: Routes = [
{
path: ':id',
component: EventPageComponent,
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class EventRoutingModule { }
And I noticed:
after build app - generated files of module: archive and event, but don't generated file for main-module.
I solved this problem with fixed in app-routing.module.ts. A added { useHash: true }:
#NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})

Angular lazy loading router configuration

I want to lazy load a module in the angular 2+ application.For that in 'app-routing.module' file I have following code.
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AbcdComponent } from './abcd/abcd.component';
const routes: Routes = [
{ path: 'portfolio', loadChildren: './lazy.module#LazyModule'},
{ path: 'dashboard', loadChildren: './lazy.module#LazyModule'},
{ path: 'abcd', component:AbcdComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
declarations: [
AbcdComponent
]
})
export class AppRoutingModule { }
Now, in Lazy Module I have the following code:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { LazyParentComponent } from './lazy-parent/lazy-parent.component';
import { LazyChildComponent } from './lazy-child/lazy-child.component';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: 'load-me', component: DashBoardComponent },
{ path: 'load-you', component: PortfolioComponent }
];
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
declarations: [
LazyParentComponent,
LazyChildComponent,
]
})
export class LazyModule { }
This is good enough to route https://example.com/portfolio/load-me to DashBoardComponent and https://example.com/portfolio/load-you to PortfolioComponent.
But the issue is I want to have a lazy module and for route like this https://example.com/portfolio I want to point to PortfolioComponent and https://example.com/dashboard to DashBoardComponent. Both components should be lazily loaded .Also, both components are in same module.I searched through internet but could not get any solution.Any help is appreciated.
That won't work. For each route inside of the AppRoutingModule, there needs to be its own module & and routing. So for example:
Dashboard Routes:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { DashboardComponent } from 'some path';
export const DashboardRoutes: Routes = [
{ path: '', component: DashboardComponent }
];
#NgModule({
imports: [
RouterModule.forChild(DashboardRoutes)
],
exports: [RouterModule],
declarations: [],
providers: [],
})
export class DashboardRoutingModule { }
Dashboard Module:
#NgModule({
imports: [DashboardRoutingModule]
})
export class DashboardModule { }
App Routes:
export const routes: Routes = [
{ path: 'portfolio', loadChildren: './PathTooPortfolio#PortfolioModule'},
{ path: 'dashboard', loadChildren: './PathToDashboard#DashboardModule'},
{ path: 'abcd', component:AbcdComponent}
];
Just setup Portfolio the same way as I have Dashboard.

How to Handle Routes for Module from NPM

I have an Angular module that I'm loading from an NPM module. How do I load the routes from it? Here is a snippet from my app.module.ts file:
import { HelloWorldModule } from 'hello-world-app-npm/hello-world-app.umd.js'; // The module loaded from NPM
const routes = [
{ path: 'hw', loadChildren: () => HelloWorldModule },
{ path: '', component: AppComponent },
]
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HelloWorldModule,
FormsModule,
HttpModule,
RouterModule.forRoot(routes)
],
exports: [RouterModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Here is how I've define my hello world module:
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { HelloWorldComponent } from './hello-world.component';
export const routes = [{ path: '', component: HelloWorldComponent }]
#NgModule({
bootstrap: [HelloWorldComponent],
declarations: [
HelloWorldComponent
],
imports: [
RouterModule.forChild(routes)
]
})
export class HelloWorldModule {
}
When I go to "/hw" I get an error in chrome saying
Uncaught (in promise): RangeError: Maximum call stack size exceeded
What am I doing wrong? How do I fix this?
I suspect it could be because of two things.
HelloWorldModule should not be appear inside AppModule import.
bootstrap: [HelloWorldComponent] inside HelloWorldModule is unnecessary.

Categories

Resources