Angular Routing not working with different components - javascript

I have two components. Component A and Component B. I want to create a navigation system in component A that on click will load the appropriate element in component B.
I know within the same component we can use routerLink and router-outlet. But how can i achieve the same in my case ??
for example:
Component A
<a routerLink="/userHome"></a>
Component B
<router-outlet></router-outlet>
And my routing module is :
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import {RouterModule, Routes} from '#angular/router';
import {UserHomeMainBodyComponent} from './components/user-home-
main-body/user-home-main-body.component';
import {UserNotificationsBodyComponent} from './components/user-
notifications-body/user-notifications-body.component';
const routes: Routes = [
{ path: 'userHome', component: UserHomeMainBodyComponent},
{path: 'userNotifications', component:UserNotificationsBodyComponent}
];
#NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AppRoutingModule { }

Related

Angular 7 :Error with Angular routing **'router-outlet'** is not a known element: [duplicate]

This question already has answers here:
'router-outlet' is not a known element
(24 answers)
Closed 8 months ago.
I have tried to include all imports to the necessary files,But I have got the following error while compiling. How could I solve it?
I have generated four differnet commonents Menu,home,contact,and about.Additional to this thare are also Header component that will later help to contain the memu bar to switch between the differnt components.And also footer component.The app-routing.ts and routes.ts files are also attached with this file,which helps for routing purpose.
'router-outlet' is not a known element:
1. If 'router-outlet' is an Angular component, then verify that it is part of this module.
2. If 'router-outlet' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the
'#NgModule.schemas' of this component to suppress this message. ("<app-header></app-header>
[ERROR ->]<router-outlet></router-outlet>
<app-footer></app-footer>"): ng:///AppModule/AppComponent.html#1:0
at syntaxError (compiler.js:1021)
at TemplateParser.push../node_modules/#angular/compiler/fesm5 /compiler.js.TemplateParser.parse (compiler.js:14830)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._parseTemplate (compiler.js:24018)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._compileTemplate (compiler.js:24005)
at compiler.js:23948
at Set.forEach (<anonymous>)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._compileComponents (compiler.js:23948)
at compiler.js:23858
at Object.then (compiler.js:1012)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:23857)
routes.ts file
import { Routes } from '#angular/router';
import { MenuComponent } from '../menu/menu.component';
import { DishdetailComponent } from '../dishdetail/dishdetail.component';
import { HomeComponent } from '../home/home.component';
import { AboutComponent } from '../about/about.component';
import { ContactComponent } from '../contact/contact.component';
export const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'menu', component: MenuComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
app-routing.module.ts file
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { routes } from './routes';
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [ RouterModule ],
declarations: []
})
export class AppRoutingModule { }
app.module.ts file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { MatToolbarModule } from '#angular/material/toolbar';
import {MatListModule} from '#angular/material/list';
import {MatGridListModule} from '#angular/material/grid-list';
import {MatCardModule} from "#angular/material/card";
import {MatButtonModule} from "#angular/material/Button";
import { FlexLayoutModule } from '#angular/flex-layout';
import 'hammerjs';
import { AppComponent } from './app.component';
import { MenuComponent } from './menu/menu.component';
import { FooterComponent} from './footer/footer.component';
import { HeaderComponent} from './header/header.component';
import { DishdetailComponent } from './dishdetail/dishdetail.component';
import { HomeComponent } from './home/home.component'
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';
import {DishService} from './services/dish.service';
import {RouterModule} from '#angular/router';
import { AppRoutingModule } from './app-routing/app-routing.module';
#NgModule({
declarations: [
AppComponent,
MenuComponent,
DishdetailComponent,
HeaderComponent,
FooterComponent,
HomeComponent,
AboutComponent,
ContactComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FlexLayoutModule,
MatToolbarModule,
MatGridListModule,
MatCardModule,
MatButtonModule,
MatListModule,
AppRoutingModule,
RouterModule
],`
`providers: [
DishService
],`
`bootstrap: [AppComponent]`
`})`
export class AppModule { }
app.component.html file
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
I see you are missing app-routing.module.ts inside the imports of AppModule
#NgModule({
imports: [
CommonModule,
routingModule
],
})
export class AppModule{ }
I noticed that in your app.module.ts file you have back ticks ``` in inappropriate places somewhere around providers & bootstrap array. I copied & pasted this from your own code so you can see it better:
...MatListModule,
AppRoutingModule,
RouterModule
],`
`providers: [
DishService
],`
`bootstrap: [AppComponent]`
`})`
export class AppModule { }
Do this:
Remove all the back ticks in the app.module.ts file like I have done below and restart your terminal. This should solve any problems you are having.
...MatListModule,
AppRoutingModule,
RouterModule
],
providers: [
DishService
],
bootstrap: [AppComponent]
})
export class AppModule { }
I copied and pasted your code and worked on the files you provided information about. With the back ticks removed, your code works fine here on my laptop. Here's the result in the gif below, route works properly & no errors in the console. Example with just home & menu components.
Final result:
I removed all other things that didn't relate to routing from your code so that it would be easier to detect errors. Here's my folder structure.
Folder structure:
And here are the contents of my files:
route.ts file:
import { Routes } from '#angular/router';
import { MenuComponent } from './menu/menu.component';
import { HomeComponent } from './menu/home.component';
export const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'menu', component: MenuComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
app.module.ts file:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { MenuComponent } from './menu/menu.component';
import { HomeComponent } from './menu/home.component';
import { AppRoutingModule } from './app-routing.module';
import { RouterModule } from '#angular/router';
#NgModule({
declarations: [
AppComponent,
HomeComponent,
MenuComponent
],
imports: [
BrowserModule,
AppRoutingModule,
RouterModule
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts file:
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
template: `
<router-outlet></router-outlet>
`
})
export class AppComponent {
}
app-routing.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { routes } from './routes';
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [ RouterModule ],
declarations: []
})
export class AppRoutingModule { }
menu.component.ts:
import { Component } from '#angular/core';
#Component({
template: '<h1>Menu Component</h1>'
})
export class MenuComponent {
}
home.component.ts:
import { Component } from '#angular/core';
#Component({
template: '<h1>Home Component</h1>'
})
export class HomeComponent {
}
Like I said, once I removed those unnecessary back ticks from the app.module.ts, your code worked fined with no errors.
I have started everything from scratch.Then my issue was fixed.I don't exactly know where is my problem.But,probably I have made routes file in separate folder.Making routes file in app-routing folder, fixed my issue.

Angular Router Doesn't Display My Component

I have a Simple Angular 2 App with a Module(InformationPagesModule module) that contains two lazy load components (Info1 Component and Info2 Component). I want to load that components when entering the following routes in the browser:
http://localhost:4200/info1 - Loads the Info1Component
http://localhost:4200/info2 - Loads the Info2Component
here the interest classes:
app.component.html
<router-outlet></router-outlet>
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { InformationPagesModule } from './information-pages/information-pages.module';
#NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
SharedModule,
InformationPagesModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule, Router } from '#angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{path:'', component: HomeComponent},
{path:'info1', loadChildren: './information-pages/information-pages.module#InformationPagesModule'},
{pathMatch:'full', path:'info2', loadChildren: './information-pages/information-pages.module#InformationPagesModule'},
{ path: '**', redirectTo: '' }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
information-pages.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { InformationPagesRoutingModule } from './information-pages-routing.module';
import { Info1Component } from './info1/info1.component';
import { Info2Component } from './info2/info2.component';
#NgModule({
imports: [
CommonModule,
InformationPagesRoutingModule
],
declarations: [Info1Component, Info2Component]
})
export class InformationPagesModule { }
information-pages-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { Info1Component } from './info1/info1.component';
import { Info2Component } from './info2/info2.component';
const routes: Routes = [
{path:'info1', component: Info1Component},
{path:'info2', component: Info2Component}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class InformationPagesRoutingModule { }
My question is, why when entering some of the routes / info1 or / info2, a blank page is displayed?
How should I configure the routes in my application so that it works?
Many Thanks!
In your app-routing.module.ts you want to declare one parent route to all routes of one lazy loaded module. That means you might want to map all routes starting with /info to your information-pages-routing.module.ts. The routes to your components (info1 and info2) you'll declare inside the lazy loaded module.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule, Router } from '#angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path:'', component: HomeComponent },
{ path: 'info', loadChildren: './information-pages/information-pages.module#InformationPagesModule' },
{ path: '**', redirectTo: '' }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
The file information-pages-routing.module.ts stays the same
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { Info1Component } from './info1/info1.component';
import { Info2Component } from './info2/info2.component';
const routes: Routes = [
{path:'info1', component: Info1Component},
{path:'info2', component: Info2Component}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class InformationPagesRoutingModule { }
You'll now be able to access the Info1Component by the route /info/info1 and the Info2Component by the route /info/info2. If you wish to access your compoents by the routes /info1 and /info2 you can either create two lazy loaded modules or just redirect /info1 to /info/info1
You might also consider loading child modules like this:
{ path: 'info', loadChildren: () => import('./information-pages/information-pages.module').then(m => m.InformationPageModule) }
Rather than
{ path: 'info', loadChildren: './information-pages/information-pages.module#InformationPagesModule' }
For more information please refer to the official documentation https://angular.io/guide/lazy-loading-ngmodules
Use this way instead of using module level routing, use AppRoutingModule for routing your components.
import { NgModule } from '#angular/core';
import { Routes, RouterModule, Router } from '#angular/router';
import { HomeComponent } from './home/home.component';
import { Info1Component } from './info1/info1.component';
import { Info2Component } from './info2/info2.component';
const routes: Routes = [
{path:'', component: HomeComponent},
{path:'info1', component: Info1Component},
{path:'info2', component: Info2Component},
{ path: '**', redirectTo: '' }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
If you use this information-pages-routing.module.ts is not required any more.

How do I use a component from a different module to be the main component in routing declarations

Angular newbie here, your patience is highly appreciated.
What am I trying to achieve?
I'm trying to use the component in my auth module(i.e login
component) as the base component for the route myapp.com/login
Assuming that when embedding in **app.component.html works fine, the same should be true when I put that in app-routing.module.ts
code for app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: '/login', component: LoginComponent}, //Cannot find name 'LoginComponent'.ts(2304)
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
My component structure
I have an auth module which has a login and register components
And the basic ng-cli generated app structure.
code for authmodule
auth.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RegisterComponent } from './register/register.component';
import { LoginComponent } from './login/login.component';
#NgModule({
declarations: [RegisterComponent, LoginComponent],
exports:[RegisterComponent,LoginComponent],
imports: [
CommonModule
]
})
export class AuthModule { }
code for app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {AppCommonsModule} from './app-commons/app-commons.module';
import {AuthModule} from './auth/auth.module'
import { HomeComponent } from './home/home.component'
#NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
AppCommonsModule,
AuthModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
You are referring to LoginComponent in routing file but not importing it.
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: '/login', component: LoginComponent}, //Cannot find name 'LoginComponent'.ts(2304)
];
Add import statement and I believe it should fix typescript error.
import { LoginComponent } from './login/login.component';
You can't directly refer components declared as part of other modules in AppRoutingModule. You have to delegate the routing of LoginComponent to AuthModule by creating an AuthRoutingModule. Then in AppRoutingModule, create a route for login and pass the control to AuthRoutingModule.
Follow the below steps to create a route for LoginComponent.
Create a new file called AuthRoutingModule and include routes for the components in AuthModule in this file.
auth-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { LoginComponent } from './login.component';
const authRoutes: Routes = [
{
path: '', // considering LoginComponent as the root path for AuthModule. This will be referred as 'login' from AppRoutingModule
pathMatch: 'full', // this is important to correctly match the empty path
component: LoginComponent
}
];
#NgModule({
imports: [RouterModule.forChild(authRoutes)],
exports: [RouterModule]
})
export class AuthRoutingModule {}
Note that forChild() method used here. RouterModule.forRoot() should be used only once and it should preferrable be there in AppRoutingModule. RouterModule.forChild() is used for creating routes for other child modules (and hence the forChild name).
Import AuthRoutingModule in AuthModule file.
Modify your AppRoutingModule file as below.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { HomeComponent } from './home.component';
const authRoutes: Routes = [
{
path: '',
pathMatch: 'full', // this is important to correctly match the empty path
component: HomeComponent
},
{
path: 'login',
loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule)
// now this will refer the root path of AuthRoutingModule
},
// Redirect all invalid URLs to HomeComponent
{
path: '**',
redirectTo: '/'
}
];
#NgModule({
imports: [RouterModule.forRoot(authRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
As shown in the above code snippet, if you want to load a component from a child module for a particular route, AppRoutingModule should redirect the control to the child module using the loadChildren property.
You would have already imported both AppRoutingModule and AuthModule in your AppModule file. Just make sure that you are loading the AppRoutingModule first and then other child modules with routing (i.e., AuthModule in your case).
If you want lazy loading, remove all child modules(with routes) from AppModule imports. More on lazy loading here.
Refer Angular official docs for more information on child modules routing.
I have also created a sample stackblitz app for demo purposes.

How to load new route in main route

Currently I'm new to Angular. I was learning routing topic but seems to stuck at a point where I want to load new route in main route. My app.module looks like
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import {HttpModule} from '#angular/http';
import {RouterModule, Routes} from '#angular/router';
// COMPONENTS
import {AppProduct} from './product.compnent';
import {AppFamily} from './family.component';
const appRoutes: Routes = [
{path: 'Family', component: AppFamily},
{path: 'Product', component: AppProduct}
]
#NgModule({
imports: [ BrowserModule, HttpModule, RouterModule.forRoot(appRoutes)],
declarations: [ AppComponent, AppFamily, AppProduct],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component
import { Component } from '#angular/core';
import {IProducts} from './IProduct';
import {ProductService} from './products.service'
// FAMILY IMPORTS
import {IFamily} from './IFamily'
import {familyService} from './family.service'
#Component({
selector: 'hello-world-app',
templateUrl: "app/app.component.html",
providers: [ProductService, familyService]
})
export class AppComponent {
iproducts: IProducts[];
familyMembers: IFamily[];
constructor(
private _product: ProductService,
private _family: familyService){
}
ngOnInit():void{
this._family.getAllFamilyMembers()
.subscribe(_successLog => {
this.familyMembers = _successLog;
})
}
}
app.component.html
<ul>
<li>
<a [routerLink]="['/Product']">
Product
</a>
</li>
<li>
<a [routerLink]="['/Family']">
Family
</a>
</li>
</ul>
<router-outlet>
</router-outlet>
Now when I serve my server all goes good except for my /Product and /Family route is loaded in <router-outlet></router-outlet> but I don't want navigation menu to appear when I visit /Product in other words I want that my route should load in parent route no child routing.
Any help would be appreciated !
You should define your children module in your appRoutes constant as this:
{ path: '/childPath',
component: ChildComponent,
children: [
{path: 'about',
loadChildren: './path/to/children.module#ModuleName'}
]
}
The answer by Mr. Deer is correct for lazy loading - however, you don't always want to do that. If you want to just have child components, you should do:
{ path: '/childPath',
component: ChildComponent,
children: [
{path: 'about',
component: SecondChildComponent
]
}
That said, lazy loading is generally preferred.

Angular nested route with param "Cannot match any routes"

Here are the 3 routes I'm working on:
game/:id
game/:id/pricing
game/:id/history
I'd like the game/:id to be the parent view, and house a <router-outlet> for the children to render inside of it. However, I keep getting this error: Cannot match any routes. URL Segment: 'game/1/history'.
Any help is appreciated.
Router Module:
import { NgModule } from "#angular/core";
import { RouterModule, Routes } from "#angular/router";
import { CommonModule } from "#angular/common";
import { GameComponent } from "./game.component";
import { GamePricingComponent } from './game-pricing.component';
import { GameHistoryComponent } from './game-history.component';
const routes: Routes = [
{ path: 'game/:id', component: GameComponent, children: [
{ path: 'pricing', component: GamePricingComponent, outlet: 'game' },
{ path: 'history', component: GameHistoryComponent, outlet: 'game' }
]},
];
#NgModule({
imports: [
RouterModule.forRoot(routes),
CommonModule
],
declarations: [
GameComponent,
GamePricingComponent,
GameHistoryComponent
],
exports: [
RouterModule
]
})
export class RoutingModule {}
GameComponent:
The game/:id route is the parent view, which has a <router-outlet name="game"> inside of it for the children (pricing & history) to render into.
import { Component } from "#angular/core";
#Component({
template: `
<div>Game stuff</div>
<router-outlet name="game"></router-outlet>
`
})
export class GameComponent {}
RootModule
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { RoutingModule } from "./routing.module";
#NgModule({
imports: [
BrowserModule,
RoutingModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export default class AppModule { }
AppComponent
import { Component } from '#angular/core';
#Component({
selector: 'app',
template: `
<div class="base">
<router-outlet></router-outlet>
</div>
`,
})
export class AppComponent {}
After a (long) while, I was able to solve this by removing the naming for the <router-outlet>. Turns out, single child router outlets 'just work' - so naming isn't required...
However, as of writing this, I'm still unaware of how to use router outlet naming within child routes. If anyone wants to elaborate here, I'd be more than appreciative. (maybe naming only works if there's more than 1 outlet at the same level?)

Categories

Resources