Why is Angular loading my root template twice - javascript

My root component is loading twice even though I have a separate component for my homepage. I have tried to use different things, such as pathMatch, separate component, etc, but no luck. When I go to /dashboard, it works just fine, but when it loads the page initially (root page), the navbar is loaded twice. I want to avoid that.+
My code looks like this:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { NavbarComponent } from './navbar/navbar.component';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { RouterModule, Routes } from '#angular/router';
import { RootComponent } from './root/root.component';
import { FeatureDashboardComponent } from '#angular/dashboard';
import { FeatureHomepageComponent } from '#angular/homepage';
const routes: Routes = [
{
path: '',
component: RootComponent,
pathMatch: 'full',
children: [
{
path: '',
component: FeatureHomepageComponent
}
]
},
{
path: 'dashboard',
component: FeatureDashboardComponent
},
{
path: '**',
redirectTo: ''
}
];
#NgModule({
declarations: [
NavbarComponent,
RootComponent
],
imports: [
BrowserModule,
NgbModule,
RouterModule.forRoot(routes)],
providers: [],
bootstrap: [RootComponent],
})
export class AppModule {}
And my HTML for RootComponent is:
<angular-navbar></angular-navbar>
<div class="layout">
<router-outlet></router-outlet>
</div>
And navbar is:
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand">My App</a>
</div>
</nav>
Example in inspect

I think the problem might be that you have the route '' loading the RootComponent and the children route tries to load FeatureHomepageComponent but is also '', which can't be effectively resolved by the router.
Try giving the children route a path that is not empty, like this:
...
{
path: '',
component: RootComponent,
pathMatch: 'full',
children: [
{
path: 'home',
component: FeatureHomepageComponent
}
]
},
...
And play with the redirect at the end, so when your application loads, it should navigate to (for example) localhost:4200/home

I think the problem is with this code:
path: '',
component: RootComponent,
you most likely do NOT want to have your RootComponent here as it would allow the RootComponent to appear within your
<router-outlet>
and could explain why you have 2 of them.
<router-outlet>
should only route to CHILDREN of your RootComponent.
In other words, no route (in your routing config) should render your RootComponent it's already being rendered. The routes there should only render what you want to display WITHIN your router-outlet, aka CHILDREN of your RootComponent
For the solution I think you just have to make this:
path: '',
component: FeatureHomepageComponent
the first path in your config (delete the RootComponet part and the children:[] part)

Instead of calling the router-outlet try to call to the exact component name

This means you have either of two: another <router-outlet></router-outlet> instance or you are instantiating the <angular-navbar></angular-navbar> in another template other than the one you show here. pathMatch has nothing to do here because the <angular-navbar></angular-navbar> component is route agnostic, meaning it is a layout component.

Related

Lazy loading for child routes is not redirecting to child

Hi for me parent routing is working fine, but for chid routes it is not redirecting and not getting errors also
in app.routing
const routes: Routes = [
{
path: 'card',
loadChildren: './cards/cards.module#CardsModule',
canActivate: [AuthGuard]
},
{
path: 'card/:id',
loadChildren: './cards/cards.module#CardsModule',
canActivate: [AuthGuard]
}]
in card-routing:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { Cardscomponent } from './cards.component';
import { AuthGuard } from '../_services/auth.guard';
import { CardDetailsComponent } from './card-details/card-details.component';
const routes: Routes = [
{ path: '', component: Cardscomponent,
children :[
{ path: ':id', component: CardDetailsComponent}
]
}
]
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CardsRoutingModule { }
localhost:4200/card is working
but localhost:4200/card/1234 is not working and not getting any error also, any help...
Check whether you have router-outlet in child component.
When the url updated but view not rendered, it usually comes down to missing router-outlet.
Learned that from developing a entire project with angular elements.
If you enable tracing, you can see all the router events are triggered successfully.

Angular route doesn't update to child's path

I have a project with file structure
app/
(all the files that get automatically built)
app-routing.module.ts
components/
layout/
top/
side/
banner/
pages/
home/
prehistory/
prehuman/
australopithecine/
homininia/
earlyHuman/
outOfAfrica/
agriculture/
ancient/
(several directories like in prehistory)
post-classical/
(several directories like in prehistory)
Each directory under pages/ was built in the CLI with ng g c ___ so that it has all the usual files. I'm trying to build the router so that it reflects the directory structure with child routers, so I have in app-routing.module.ts the following code. Note that since I'm at the early stages I haven't fully written out all the children and their sub-children, I just wanted to get a small part of it built and tested before building out the rest.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './components/pages/home/home.component';
import { PrehistoryComponent } from './components/pages/prehistory/prehistory.component';
export const routes: Routes = [
{path:'', children: [
{path:'prehistory', component:PrehistoryComponent},
{path:'', component:HomeComponent},
]}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}
In my AppComponent I used header and other tags to control CSS styles, but the important part is that there's a portion of the screen reserved for the header, for the side, and then the content which is the part that changes based on the address.
app.component.html
<header>
<app-top></app-top>
</header>
<aside>
<app-side></app-side>
</aside>
<content>
<router-outlet></router-outlet>
</content>
And the links are in the TopComponent.
top.component.html
<div><app-banner></app-banner></div>
<div id="breadcrumb">
<nav>
<a [routerLink]="['']" routerLinkActive="active">Home</a>
<a (mouseover)="onHover()" [routerLink]="['prehistory']" routerLinkActive="active">Prehistory</a>
</nav>
</div>
top.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-top',
templateUrl: './top.component.html',
styleUrls: ['./top.component.css'],
})
export class TopComponent implements OnInit {
constructor(private route: ActivatedRoute) {
}
onHover = function() {
console.log(this.route.url._value[0]);
}
ngOnInit() {
}
}
When my browser navigates to /prehistory the page loads correctly but the console prints out "" indicating the root route URL. And when I've also tried logging to console the parent directory, it prints null, confirming that the activated route is representing the root directory even though the page has navigated away from it.
home.component.html
<p>
home works!
</p>
<router-outlet></router-outlet>
prehistory.component.html
<p>
prehistory works!
</p>
<router-outlet></router-outlet>
Using .forChild instead of .forRoot seems to break the page. I am wondering if maybe I need to use a service to pass information around? Like maybe I need a service to somehow collect the current route from the content tag and pass that over to the TopComponent? But I'm not sure how I would get a service that collects the route from the content tag.
I think the most important is to activate this property: useHash: true and then manage the path correctly with the name of each component.
Try changing to this code:
export const routes: Routes = [
{ path: 'home', component: HomeComponent},
{path:'children', component: [
{path:'prehistory', component:PrehistoryComponent},
{path:'**', component:HomeComponent},
]},
{ path: '**', pathMatch: 'full', redirectTo: 'home'}
];
#NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule]
})

Error when creating a navigate function through button click using router Angular 6

I am new to angular 6 and it's navigation/routing, I am sorry if this sounds obvious.
I am trying to have a button with a function to navigate to the login page, but I keep getting this error:
" Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'login'
Error: Cannot match any routes. URL Segment: 'login'
at ApplyRedirects.push../node_modules/#angular/router/fesm5/router.js.ApplyRedirects.noMatchError "
my html is :
<button ion-button (click) = "openLogin()" >Efetuar login</button>
my router is :
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { LoginComponent } from './login/login.component';
const routes: Routes = [
{
path: 'login',
outlet: 'login',
component: LoginComponent
},
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
I've been researching on the matter and as long as the path corresponds to the path defined in the router there shouldn't be any issue but I keep getting this error.
Named router-outlet is quite different than normal router-outlet.
This is how named router-outlet works
1.Add outlet to your route object as you are already doing now
{
path: 'login',
outlet: 'login',
component: LoginComponent
},
2.Add a name attribute to router-outlet tag
<router-outlet name="login"></router-outlet>
3.Using router.navigate
this.router.navigate([{ outlets: { login: [ 'login' ] }}]);
4.Using routerLink
[routerLink]="[{ outlets: { login: ['login'] } }]"
I would recommend you to read this post aswell.
Try to implement this in your imports this way:
RouterModule.forRoot(routes, {useHash: true});
instead of:
RouterModule.forRoot(routes)

In Angular2 routing, the URL changed but the content doesn't update

I am a beginner of Angular2. When I am learning angular2 routing service from https://angular.io/tutorial/toh-pt5. I want to have herocomponent always displayed so I in the app.component.html like this:
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard">Dashboard</a>
<a routerLink="/heroes">Heroes</a>
<a routerLink="/dummy">Dummy</a>
</nav>
<app-heroes></app-heroes>
<router-outlet></router-outlet>
<app-messages></app-messages>
And here is the app-routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import {DummyComponentComponent} from './dummy-component/dummy-component.component';
const routes: Routes = [
{ path: '', redirectTo: '/', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent },
{path: 'dummy',component:DummyComponentComponent}
];
#NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
Strangely, when I click a hero on /dashboard or /heroes page it can direct to the correct URL and show the correct hero detail.
However, when I am on /detail/{{hero.id}} and click the hero on the hero component it can redirect the URL but the content in doesn't update. Can someone please help me with this?
if below is not issue then it should be issue that you are just changing parameter url that is reason its not updating
//put this code in your hero.component.ts file
ngOnInit() {
this.route.params.subscribe((params) => {
this.id = +params['id'];
this.loadComponentAgain();
});
}
above code monitor change in param value and update your component according to it.
There is issue because of this html
<app-heroes></app-heroes>
<router-outlet></router-outlet>
you are loading app-heroes component out side router-outlet, it should be loaded under router-outlet, so you should do this
<!-- <app-heroes></app-heroes> remove this-->
<router-outlet></router-outlet>
For changing a route with dynamic value you need to set your routerLink like this
[routerLink]="['/detail',hero.id]"

How to pass component into router-outlet

I have an app component an its use router-outlet, and a main component (what is loaded at router-outlet)
Now I would like to place packages in that component where we can insert widgets.
App component:
<cover></cover>
<div fxFlexFill fxLayout="row" fxLayoutAlign="stretch">
<div fxFlex>
<router-outlet></router-outlet>
</div>
</div>
Main component:
<app-header></app-header>
<main-widget></main-widget> //place where I would like to load custom content
<left-widget></left-widget> //place where I would like to load custom content
<right-widget></right-widget> //place where I would like to load custom content
Main component is come from a coreModul(share module) - this is a framework we have no access to it on project level.
So I would like to put content into widgets, but have no idea how to do that.
The hard thing to me is how to pass a component into a router-outlet and show it in right place. Its possible to use ng-templates in this case?
EDIT:
App routing:
import { RouterModule, Routes } from '#angular/router';
import {
LoginComponent,
LoginGuard,
MainComponent,
} from './../_system';
import { USERS_ROUTES, UsersComponent } from './../users';
const APP_ROUTES: Routes = [
{ path: 'login', component: LoginComponent },
{ path: '', component:MainComponent, canActivate: [LoginGuard], children: [
{ path: 'users', children: USERS_ROUTES},
{ path: '', redirectTo: '/login', pathMatch: 'full'},
{ path: '**', redirectTo: '/questions'}
]}
];
export const AppRoutingModule = RouterModule.forRoot(APP_ROUTES);

Categories

Resources