I have define 2 Routes LoginComponent and DashboardComponent and their is one main component which is the base component appComponent (which i have not used)
What I want is:
First Load the LoginComponent and then I Login Successfully then I want to Load the DashboardComponent.
What I have done is:
I have make the base component to the loginComponent as a selector in index.html page and when I successfully login the the LoginComponent View not Removed and Replace to Dashboard Page.
Here is my Code:
Routes:
const appRoutes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: DashboardComponent },
{ path: '', redirectTo: '/login',pathMatch:'full' },
{ path: '**', component: NotFound404Component }
];
Used this for login function:
this.router.navigate(['/dashboard']);
Any help would appriciated.
Related
i have a question.
I have 2 router outlets in my angular app.
First one is in app.component.html and is loaded for regular users and site visitors. The router works fine and all components in it are being perfectly loaded
<ng-container *ngIf="!isAdmin">
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
</ng-container>
Here is the appRoutingModule, which is forRoot
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { HomeComponent } from './home/home.component';
import { CatalogComponent } from './movies/catalog/catalog.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { AuthActivate } from './core/guards/auth.activate';
import { AboutComponent } from './about/about.component';
import { ReqComponent } from './req/req.component';
const routes: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: '/home'
},
{
path: 'home',
component: HomeComponent,
},
{
path: 'about',
component: AboutComponent
},
{
path: 'catalog',
component: CatalogComponent,
canActivate: [AuthActivate],
data: {
authenticationRequired: true,
authenticationFailureRedirectUrl: '/',
}
},
{
path: 'req',
component: ReqComponent,
canActivate: [AuthActivate],
data: {
authenticationRequired: true,
authenticationFailureRedirectUrl: '/',
}
},
// all others
{
path: '**',
component: NotFoundComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes, {enableTracing: true})],
exports: [RouterModule]
})
export class AppRoutingModule { }
I have a second route outlet for admin users only. If user that logs is admin, the dashboard is being showed. It loads entirerly different css, header and footer. The outlet has its own routing, which works.
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AuthActivate } from '../core/guards/auth.activate';
import { UserslistComponent } from './userslist/userslist.component';
const routes: Routes = [
{
path: 'admin-home',
component: UserslistComponent,
canActivate: [AuthActivate],
outlet: 'admin',
data: {
authenticationRequired: true,
admin: true,
authenticationFailureRedirectUrl: '/about',
}
},
{
path: 'userlist',
component: UserslistComponent,
canActivate: [AuthActivate],
outlet: 'admin',
data: {
authenticationRequired: true,
admin: true,
authenticationFailureRedirectUrl: '/about',
}
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AdminRoutingModule { }
the outlet in app.component.html
<ng-container *ngIf="isAdmin">
<app-adminheader></app-adminheader>
<router-outlet name="admin"></router-outlet>
<app-adminfooter></app-adminfooter>
</ng-container>
So both outlets work fine for different users. Header and footer depending on user permissions are loaded and displayed correctly.
But if i want to render HTML in the page body in between header and footer for admin, for example as the root displays, under 'userlist' load UserListComponent. the html of this userListComponent is not being displayed
I tried with 5 newly created components.
Is there any explanation on this?
Thank you for your time :)
And if checked in DOM, we see that the router-outlet is shown, but it is empty
schreenshot shows empty dom, white space, where the component userslistcomponent should be rendered and on the left side - part of the adminheadercomponent, which displays correctly
How do you access the "admin" routes?
With that implementation the URL that should show the proper admin component should look like this:
'/home/(admin:admin-home)'
are you doing that?
I'm not sure if you get the idea of secondary routes correctly :) - secondary routes (so the ones with outlet) are kind of like a child to the main route - I mean that in one time we can use two router-outlets.
In your case there are just two different route trees - one for regular users and one for admin. Therefore you shouldn't use secondary routing, but instead design the architecture like this:
<ng-container *ngIf="admin">
<app-admin-header></app-admin-header>
<router-outlet></router-outlet>
<app-admin-footer></app-admin-footer>
</ng-container>
<ng-container *ngIf="!admin">
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
</ng-container>
and the routes config:
const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'admin-home',
component: AdminHomeComponent,
},
...
]
Then you can access regular home by resolving route /home/ and admin home with /admin-home/. These two routes are on the same level - think about them as two separate ways to go :)
Thanks for the answer
Hi answering your question, i do access admin routes like this
const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'admin-home',
component: AdminHomeComponent,
outlet: "admin"
},
...
]
. with outlet: "admin" i enter the admin router outlet. I use different modules for different paths. For example, for user i have this routing module
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AuthActivate } from '../core/guards/auth.activate';
import { LoginComponent } from './login/login.component';
import { ProfileComponent } from './profile/profile.component';
import { RegisterComponent } from './register/register.component';
import { EditProfileComponent } from './edit-profile/edit-profile.component';
const routes: Routes = [
{
path: 'login',
component: LoginComponent,
canActivate: [AuthActivate],
data: {
authenticationRequired: false,
authenticationFailureRedirectUrl: '/',
}
},
{
path: 'register',
component: RegisterComponent,
canActivate: [AuthActivate],
data: {
authenticationRequired: false,
authenticationFailureRedirectUrl: '/',
}
},
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthActivate],
data: {
authenticationRequired: true,
authenticationFailureRedirectUrl: '/login',
}
},
{
path: 'edit-profile',
component: EditProfileComponent,
canActivate: [AuthActivate],
data: {
authenticationRequired: true,
authenticationFailureRedirectUrl: '/',
}
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserRoutingModule { }
Meaning i do separate the routes specific for the user in this module. This works. I did separate the routes for the admin as well for user and quest and i decided to use another outlet for admins only, this is when i realised html is no longer rendered for the components, represented by this new outlet. the components i render with
user-routing.module.ts
guest-routing.module.ts
work fine, but they get the routes from the main outlet
I will try to use the main outlet for the admin routes as well, as you proposed , will see thanks :)
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);
I have a question regarding routing submenu elements in Angular 2.
The directory of my project looks like:
-app
---login
---registration
---mainApp (this is the main body of the app, with a static content as menu, with few links)
-----subMenu1 (link to some content)
-------(some files here)
-----subMenu2 (link to some content)
-------(some files here)
-----subMenu3 (link to some content)
-------(some files here)
---app.component.ts
---app.component.html
---app.module.ts
---app.routing
---index.ts
How does it works? First view is the login and there you have two possibilities, to enter the mainApp or enter registration form. It works fine. But now I need to handle the routing between the mainApp and sub items from this mainApp. The mainApp content is just a sidemenu, which doesn't disappear. It is always on screen, only content from sidemenu elements is changing.
What is my problem:
Do I need to provide another routing file to handle the routing between the mainApp static menu elements and the dynamic content? Or am I able to do it just from this file which handles routing between the app and login, registration and mainApp?
And if I have to make another routing file, how would it look like?
My actual routing file looks like:
import { Routes, RouterModule } from '#angular/router';
import { MainAppComponent} from './mainApp/index';
import { LoginComponent } from './login/index';
import { RegistrationComponent } from './registration/index';
const appRoutes: Routes = [
{ path: '', component: LoginComponent },
{ path: 'mainApp', component: MainAppComponent },
{ path: 'registration', component: RegistrationComponent },
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
Let's say that I provide another routing file, would it look like this?
import { Routes, RouterModule } from '#angular/router';
import { subMenu1Component } from './subMenu1/index';
import { subMenu2Component } from './subMenu2/index';
import { subMenu3Component } from './subMenu3/index';
const appRoutes: Routes = [
{ path: '', component: mainAppComponent},
{ path: 'subMenu1', component: subMenu1Component },
{ path: 'subMenu2', component: subMenu2Component },
{ path: 'subMenu3', component: subMenu3Component },
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
I like to split my routes off into layouts. So typically I do a secure layout and a public layout. This way I can control the authentication of the website and protect data that was meant to be secure.
In order to do this I keep a file structure as shown below,
/app.module.ts
/app.routing.ts
/layouts/secure.component.ts
/layouts/secure.component.html
/layouts/public.component.ts
/layouts/public.component.html
/secure/profile.component.ts
/secure/profile.component.html
/secure/secure.routes.ts
/public/home.component.ts
/public/home.component.html
/public/public.routes.ts
Explanation
Initially we need to register all of our components and setup the routes.
Register Components
/app.module.ts
//Layouts
import { PublicComponent } from './layouts/public.component';
import { SecureComponent } from './layouts/secure.component';
import { HomeComponent } from './public/home.component';
import { ProfileComponent } from './secure/profile.component';
#NgModule({
declarations: [
AppComponent,
PublicComponent,
SecureComponent,
HomeComponent,
ProfileComponent
],
providers: [
Guard,
Auth
]
Take special notice to the Auth under providers. This is what will help us secure the secure layout.
Next we will setup the routes.
app.routing.ts
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full', },
{ path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES },
{ path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES }
];
As you can see the [Guard] is setup using the Auth provider and is a service I use to secure the secure layouts. Now that each of these routes actually have children routes we can set those routes up to control the actual navigation of our app.
It is important to understand. These routes will direct traffic to the correct layout. Then depending on the route the child routes take over. Which in your case would be your sub components.
/secure/secure.routes.ts
import { ProfileComponent } from './profile.component';
export const SECURE_ROUTES: Routes = [
{ path: '', redirectTo: 'profile', pathMatch: 'full' },
{ path: 'profile', component: ProfileComponent },
];
Remember to import your component to the routes file so it knows which class to call when the route is enabled.
For extra credit I will go ahead and throw in a service to provide auth. This will show you how to protect your routes.
guard.service.ts
import { Injectable } from '#angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '#angular/router';
import { Auth } from './auth.service';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class Guard implements CanActivate {
constructor(protected router: Router, protected auth: Auth ) {}
canActivate() {
if (localStorage.getItem('access_token')) {
// logged in so return true
return true;
}
// not logged in so redirect to login page
this.router.navigate(['/home']);
return false;
}
}
By storing a token in the local storage we can check to see if it exist and authenticate the user. Once they meet the criteria they gain access to the secure routes.
Let me know if you have anymore questions.
Heres my router config:
import { RouterConfig } from '#angular/router';
...
export const AppRoutes : RouterConfig = [
{
path: '',
redirectTo: 'myview',
pathMatch: 'full'
},
{
path: 'myview',
component: ViewComponent,
children: [{
path: 'hello',
component: HelloComponent
}]
},
];
When I try to load the page I get the following error:
EXCEPTION: Error: Uncaught (in promise): Error: Cannot match any routes: ''
However, when I make the child route a sibling, like this:
export const AppRoutes : RouterConfig = [
{
path: '',
redirectTo: 'myview',
pathMatch: 'full'
},
{
path: 'myview',
component: ViewComponent
},
{
path: 'hello',
component: HelloComponent
}
];
I am able to load the page fine without any errors. What am I doing wrong?
Because the way you have designed it is on initial load it is landing on ViewComponent component but ViewComponent has child so have to redirect to inner component.
You need to add one more route to children routes which will redirect '' to hello component.
export const AppRoutes: RouterConfig = [
{ path: '', redirectTo: 'myview', pathMatch: 'full'},
{ path: 'myview', component: ViewComponent,
children: [
{ path: '', pathMatch: 'full', redirectTo: 'hello' }, //added redirection to hello
{ path: 'hello', component: HelloComponent }
]
}
];
Note: Make sure you have <router-outlet></router-outlet> in myview component HTML so that child route view can be shown
correctly.
You are not using any route for '' in your RouterConfig.
As after redirect the new path will be https://yourdomain/myview/. And for this you have only created https://yourdomain/myview/hello route in routeCofig
I have created an app in angular 2. You can check the source here on Github.
Just add following line to your children path array:
{path: '', component: HelloComponent }
Check hero.routes.ts and dragon.routes.ts files they will help you understand routing more clearly. Hope it will help. Thank you.
I'm building an Angular 2 test app. I'm using the new router and it seemed to be working fine this was my code:
export class Topbar {
constructor(#Inject(Router) router: Router) {
router.config([
{path: '/displays', as: 'display', component: Display}
]);
}
}
This works now as soon as I add a second route like this I get an error:
export class Topbar {
constructor(#Inject(Router) router: Router) {
router.config([
{path: '/', as: 'home', component: MyApp},
{path: '/displays', as: 'display', component: Display}
]);
}
}
This is the error:
Configuration '/' conflicts with existing route '/'
Is this a bug or am I doing something wrong here?
I guess,
Your router config goes in your App component
and '/' routes to component: Home rather than MyApp
something like this
export class MyApp {
constructor(#Inject(Router) router: Router) {
router.config([
{ path: '/', as: 'home', component: Home },
{ path: '/about', as: 'about', component: About }
]);
}
}