Router not correctly loading default route on application load - javascript

I've been struggling with this issue for the past day and a half and still have made no progress. Currently, I am attempting to load my angular app and have it default to a particular page when the application is bootstrapped. Unfortunately, it redirects to a different route.
I'm trying to go to:
https://clwd0002278/ControlTower/NICK/UI/#/
When I initially load, though, it goes to https://clwd0002278/ControlTower/NICK/UI/#/ControlTower/NICK/UI/, which results in the 404 page being hit.
I'll also try to go to https://clwd0002278/ControlTower/NICK/UI/ with the same result as above.
Here's the code so someone can try to make sense of this:
const routes: Routes = [
{path: '', redirectTo: 'patients', pathMatch: 'full'},
{path: 'dashboard', component: DashboardComponent},
{path: 'notifications', component: NotificationsComponent},
{path: 'patients', component: PatientListComponent},
{path: '404', component: NotFoundComponent},
{path: '**', component: NotFoundComponent},
];
#NgModule({
imports: [
RouterModule.forRoot(routes, {useHash: true})
],
exports: [RouterModule]
})
export class AppRoutingModule {
}
Here's the base-href on the html page:
<base href="#">
I have tried changing base-href and deploy-url in the build script, as well as omitting them entirely. I'm just not sure what I'm missing at this point.
Any help would be appreciated, and just ask if you need more information.
Edit:
The application exists at https://clwd0002278/ControlTower/NICK/UI/ and NOT at https://clwd0002278/.

Add
<head>
<base href="/ControlTower/NICK/UI">
...
</head>
to your index.html
or provide int in AppModule like
import { APP_BASE_HREF } from '#angular/common';
...
providers: [{APP_BASE_HREF, useValue: '/ControlTower/NICK/UI'}]
See also
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
https://angular.io/api/common/APP_BASE_HREF

Always your default route must be at the before the path "**".
{path: '404', component: NotFoundComponent},
{path: '', redirectTo: 'patients', pathMatch: 'full'},
{path: '**', component: NotFoundComponent},
Refer
https://angular.io/guide/router

So, it turns out that there was some code from ngrx that was pulled in from our base project package that kept throwing the location.pathname onto the end of the url for the angular/ngrx routing packages. I'm so frustrated and yet so relieved to have finally resolved this issue.
I commented out the reducers and initial state related to this to solve my issue. So, be careful of how ngrx interacts with your url!

Related

How to render a component without rendering AppComponent at all times?

I want to render 2 components (AppComponent and UserComponent) without having to render AppComponent at all times. Here's what my code looks like:
app.routing.module.ts
const routes: Routes = [
{
path: '', component: AppComponent
},
{
path: 'user', component: UserComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.component.html
<div>
I'm in the app component
</div>
<router-outlet></router-outlet>
Now for some reason "I'm in the app component" text is rendered 2 times as you can see in the picture:
Now when I go to route '/user' I see this:
so my question is How can I only see "I'm in the app component" text when on on '/' route and
when I'm on '/user' route only see "user works!"? Thanks a lot in advance!
AppComponent renders by default as its the root component. You would need to create another component and use that as your home component. Please check the updated stackblitz.
My answer is: Don't. Make an OtherComponent, then remove all but the <router-outlet> tag from AppComponent.html.
Treat that AppComponent as the top level that everything flows through. Angular is very opinionated, and if you do things in a way that's not standard practice, Angular will act like it's meant to.
If the two branches should really be that separate, consider having separate apps.
This is because default route '' matches both '' and 'user' paths. Try setting pathMatch: 'full' to the AppComponent and it shouldn't render on other routes:
{
path: '',
component: AppComponent
pathMatch: 'full'
}
But more of an issue here is that the default route should be a separate component and your AppComponent should be the one that holds the router-outlet.

Adding :id to guarded component path causes infinite loop?

This stackblitz demo should not render because of the :id path variable in the route to the guarded HelloComponent.
{ path: ':id', component: HelloComponent, canActivate: [AuthGuard] },
{ path: '', component: CollectionPageComponent, canActivate: [AuthGuard] }];
If :id is removed, then the login view renders, since both paths will be guarded, but if the :id variable is added back to the path, the demo spins forever.
Is this a bug or am I violating some router principle by adding :id to this location?
Note that I replaced the ViewBook component with a HelloComponent just for trouble shooting purposes. The books module is lazy and the way that this is supposed to work is that if the user authenticates and selects a book in search the book can be shown with the path books/4545342, which would trigger the :id path, but if just books is requested, without a path parameter then the book collection is shown.
I'm using this demo as a reference point. Is uses a essentially the same routing configuration.
I tried flipping the path parameters here. It seems in older versions of Angular the order does not matter, but now it does.
Filed a bug report here
When using the router, you have to be careful where you import modules. Ideally, you won't import a lazy loaded module in your application anywhere.
In your case, you're importing the book module into your app module. This adds the routes to the router config at the root level. The router does fancy unknown-to-me things with lazy loaded modules. Routes that cannot be activated won't be added to the config.
See new config after removing book module from app module:
0: {path: "login", component: ƒ}
1: {path: "", redirectTo: "books", pathMatch: "full"}
2: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
3: {path: "**", component: ƒ}
VS before the move:
0: {path: ":id", component: ƒ}
1: {path: "", component: ƒ}
2: {path: "login", component: ƒ}
3: {path: "", redirectTo: "books", pathMatch: "full"}
4: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
5: {path: "**", component: ƒ}
To fix: simply don't import your book module in the app module. In your case, you'll need to import the HttpClientModule in your book module.
Try this, pay attention I change the order, and added pathMatch to '' route,
{ path: '', component: CollectionPageComponent, pathMatch: 'full', canActivate: [AuthGuard] },
{ path: ':id', component: HelloComponent, canActivate: [AuthGuard] },
if the issue is not solved let me know to delete my answer

Angular Routes: Problem defining a NotFoundComponent with multiple routings files

I am creating a NotFoundComponent so that every non-existing url, a friendly page will apear to the user.
My Angular 6 project has 5 features(CRUDL):
CompanyComponent,
EmployeeComponent,
BranchComponent,
BenefitsComponent,
MainComponent
Each component have it own .module and .routing, for example the company.routing.ts defines the route like this:
export const routes: Routes = [
{
path: "branch",
component: EmptyComponent,
}
...
#NgModule({
imports: [
RouterModule.forChild(routes),
...
it also defines its childrens, like path: "branch/:id".
So, i have no problem with the way i built the routing.
The problem I am facing now is the way I can define a path to the NotFoundComponent.
Because I don't have a single file where I define my routes, if I put the definition of the /404 page on the on the bottom of routers definition in the main.routing.ts, every other route defined on the features(like the company.routing.ts) will be redirected to the /404, since angular uses the first match strategy.
Things i tried so far:
on the main.routing.ts:
export const routes: Routes = [
{
path: "main",
component: MainComponent,
},
{
path: "404",
resolve: {
routeTitle: TitleResolver,
},
component: NotFoundComponent,
},
{
path: "",
pathMatch: "full",
redirectTo: "/main",
},
{
path: "**",
redirectTo: "/404",
}
if I put this way, when I try accessing the route /company (defined in the company.routing.ts) it will be redirected to the /404.
I also tried defining it on any a routing of one of my features, like on the company.routing.ts
{
path: "**",
redirectTo: "/404",
}
Than, a funny thing happened, if I define this piece of code on the benefits.routing.ts, i can access /benefits but /branch, /employee and the rest of the routes will be redirected to /404.
if I define it on branch, I can access /benefits, /branch but /employee and the rest of the routes will be redirected to /404.
I could just place this code on the last feature loaded and it would work but I would like to know if I can solve this with another approach, can't I define a route that I want to be the last one loaded?
thanks in advance.

Angular 4 after reloading redirect me to base href instead of staying at the same page

I have created an Angular 4 app with routing, canAccess, AuthGuard. So ex. I am on page: http://localhost:4200/#/items and routing on diffrent pages looks great. But when I reload/refresh page in browser it automatically redirect me to http://localhost:4200/#/. I tried something with APP_BASE_HREF in providers or keeping current href in localStorage but none of this work at all. Does anyone have any clue?
Below I post kind of configuration which might help you:
<base href="/">
imports: [
RouterModule.forRoot([
{path: '', component: LoginComponent},
{path: 'items', component: ItemListComponent, canActivate: [AuthGuard]},
])
],
providers: [
{provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptor, multi: true},
{provide: LocationStrategy, useClass: HashLocationStrategy},
AuthenticationService,
AuthGuard,
],

Angular 4 lazy load module doesn't work with named child outlet

I am trying to implement lazy loading for a module. This module has a bunch of child routes with a unique outlet name. This doesn't seem to work when I try to visit the routes.
This can be seems from this example that I saved: https://plnkr.co/edit/NNXAoZItM00RIIxzemts?p=preview
You can see that I have the child route set to
{ path: 'list', component: HeroListComponent, outlet: 'abc' },
in hero-routing.module.ts
and router outlet to:
<router-outlet name="abc"></router-outlet>
in hero.component.ts
I should be able to visit localhost:3000/heroes/(abc:list) when I am running it locally, but it doesn't seem to work.
Note: You can run the plunker example locally by download the zip file and running npm install then npm start.
The child routes do not seem to work with default unamed routes.
Change the lazy loaded module routes to include a redirect from default unamed route to a named route.
const routes: Routes = [
{ path: '', redirectTo: 'start', pathMatch: 'full' },
{ path: 'start', component: HeroComponent,
children: [
{ path: 'list', component: HeroListComponent, outlet: 'abc' },
{ path: ':id', component: HeroDetailComponent }
]
}
];
Finally change the navigation link for 'heroes' lazy loaded module to include the named outlet information. Be sure to specify the complete url as '/heroes/start', do not leave it to the default '/heroes'.
<a [routerLink]="['/heroes/start',{outlets: {abc:['list']}}]"
routerLinkActive="active">Heroes</a>

Categories

Resources