Angular 2 (2.0.0-rc.4) Login/admin router template pathing - angularjs

Good day to you all. Hopefully a quick question. =)
I have a login page with the route setup as /login
I also have other routes/pages set up e.g. /dashboard, /history, /sales and those pages all share a sidebar navigation.
The ploblem i am having is that i need the login page to not show the sidebar and only show the form. Once logged in i need to show the sidebar and have the right side of the page change to the content of the requested url.
for my routes i am using
import { provideRouter, RouterConfig } from '#angular/router';
import { DashboardComponent } from './components/pages/dashboard.component';
import { HistoryComponent } from './components/pages/history.component';
import { SalesComponent } from './components/pages/sales.component';
import { LoginComponent } from './components/pages/login.component';
const routes: RouterConfig = [
{ path: '', redirectTo:'/login', pathMatch: 'full'},
{ path: 'dashboard', component: DashboardComponent},
{ path: 'history', component: HistoryComponent },
{ path: 'sales', component: SalesComponent },
{ path: 'login', component: LoginComponent},
{ path: '**', component: ErrorComponent }
];
export const appRouterProviders = [
provideRouter(routes)
];
for my app.ts
import { Component, } from '#angular/core';
import { ROUTER_DIRECTIVES} from '#angular/router';
import { HTTP_PROVIDERS} from '#angular/http';
#Component({
moduleId: module.id,
selector: 'my-app',
template: '<router-outlet></router-outlet>',
directives: [ROUTER_DIRECTIVES],
providers: [HTTP_PROVIDERS]
})
export class AppComponent {
}

Related

Facing issue while Lazy loading a module ( Cannot find module)

I am working on creating lazy loaded modules In spite of all my efforts, I think I am missing something here due to which I'm unable to load modules on demand.
I have my project structure as below:
app
-users
-homeComponent
-signupComponent
-users.routing.module.ts
-users.module.ts
-list
-createListComponent
-dashboardComponent
-list.routing.module.ts
-list.module.ts
users-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
import { SignupComponent } from './signup/signup.component';
const routes: Routes = [
{
path: "",
component: HomeComponent
},
{
path: "/signup",
component: SignupComponent
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UsersRoutingModule { }
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{
path: 'signup',
loadChildren: './app/users/users.module#UsersModule',
},
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
I have added relative path in my loadChildren tag, but I am still getting an error saying "cannot load module". I have tried different websites but I feel I am missing a basic part here.
Any help would be appreciated.
Add users component in the users module.
Add users component will be the container where other child component get loaded.
Add <router-outlet></router-outlet> in the app componentcompoent
users-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
import { SignupComponent } from './signup/signup.component';
import { UsersComponent } from './users.component';
const routes: Routes = [
{
path: '',
component: UsersComponent, // will be bootstrap component for users module
children: [ // will children for user module
{
path: 'signup',
component: SignupComponent,
},
{
path: 'home',
component: HomeComponent,
},
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class UsersRoutingModule { }
Here is working demo https://stackblitz.com/edit/angular-ivy-j6wtlk
Lazy Loading Syntax now uses promise / observable, Try this:
const routes: Routes = [
{
path: 'signup',
loadChildren: () => import('./app/users/users.module').then(u => u.UsersModule)
},
];
I think there is a problem with your route configuration.
const routes: Routes = [
{
path: "",
component: HomeComponent
},
{
path: "/signup",
component: SignupComponent
}
];
With a configuration like this, the SignupComponent route object will never be reached, because Angular router will go through the configuration arrays until it finds the first match(in a DFS manner) and since every possible route matches "", it will search from there.
What I think you can do is to add the pathMatch: 'full' option:
const routes: Routes = [
{
path: "",
component: HomeComponent,
pathMatch: 'full',
},
{
path: "/signup",
component: SignupComponent
}
];
What you could also do is to add the HomeComponent route add the end of the array as it is.
Working code in stackblitz
just make the changes as below, as lazy loaded module does not require path value again and thus can be left blank
// users-routing.module.ts
const routes: Routes = [
{
path: '', // leave blank
component: SignupComponent,
},
];
<!-- app.component.html -->
<p> home works</p>
<router-outlet></router-outlet>

Getting nothing when define routes in Angular2

I am new to Angular2. I am trying to create routes as given here.
I created three components like HeaderComponent, SidebarComponent and UiElementsComponents. All of these are declared in main.module file (root module). Everything works great till now. But when I define routes it stops from displaying anything. Even doesn't display any error. Here is my code.
main.module.ts
//Main (root) module of App is defined here.
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { BrowserModule } from '#angular/platform-browser';
import { MainComponent } from './../components/main.component';
import { HeaderComponent } from './../components/header.component';
import { SidebarComponent } from './../components/sidebar.component';
import { UiElementsComponent } from './../components/ui-elements.component';
const routes: Routes = [
{ path: '', redirectTo: '/test', pathMatch: 'full' },
{ path: 'test', component: UiElementsComponent},
];
// The root module of the pratham app.
#NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(routes)
],
declarations: [
MainComponent,
HeaderComponent,
SidebarComponent,
UiElementsComponent
],
bootstrap: [ MainComponent ]
})
export class MainModule { }
main.component.ts
//Main (root) component of Pratham is defined here.
import { Component } from '#angular/core';
#Component({
selector: 'prtm-main',
template: `<div class="prtm-wrapper">
<prtm-header-section></prtm-header-section>
<div class="prtm-main">
<prtm-sidebar-section></prtm-sidebar-section>
<router-outlet></router-outlet>
</div>
</div>`
})
export class MainComponent { }
I have already wasted hours on finding out the issue. Can you please tell me what am I missing?

Angular 2 module lazy-loading not working

I'm trying to get my head around Angular 2 (RC5) lazy-loading of modules by building a basic structure of a site with two sections, welcome and backend (think login page and main site). I've set it up following the Angular 2 docs on feature modules, one for the welcome section and one for the backend. It correctly defaults to the welcome component but my button in the welcome component that's supposed to link to the 'backend' route goes to 'welcome/backend' instead. Typing in the url with just /backend goes to /backend/welcome. Here's my app.routing.ts file:
import { Routes, RouterModule } from '#angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'welcome', pathMatch: 'full'},
{ path: 'backend', loadChildren: 'app/backend/backend.module' }
];
export const routing = RouterModule.forRoot(routes);
And my welcome.routing.ts:
import { RouterModule } from '#angular/router';
import { WelcomeComponent } from './welcome.component';
export const routing = RouterModule.forChild([
{ path: 'welcome', component: WelcomeComponent}
]);
And my welcome.component.ts:
import { Component } from '#angular/core';
#Component({
template: `
<h2>Welcome</h2>
<nav><a routerLink="backend">Login</a></nav>
`
})
export class WelcomeComponent { }
Anyway, here's plunk of the whole app to make it easier Plunkr. The ones that matter are in welcome and backend folders. Clicking Login should show Backend with a Logout button which takes you back to the Welcome page.
Any suggestions would be appreciated.
There were quite a few things wrong with your plunkr. Here is the working example https://plnkr.co/edit/QciaI8?p=preview
The router link was moved to app.component
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>Module Test</h1>
<nav><a routerLink="../backend">Logins</a></nav>
<router-outlet></router-outlet>
`
})
export class AppComponent { }
You also need backend.routing.ts
import { Routes,
RouterModule } from '#angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', redirectTo: 'backend', pathMatch: 'full'},
{ path: 'backend', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
Backend.module was changed to
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
#NgModule({
imports: [ routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
I finally go it working by figuring out that router stacks routes from nested modules (e.g. 'backend' route in app.routing and 'backend' in backend.routing results in '/backend/backend' as the url). So the solution was to have a backend.routing.ts with a single route of { path: '', component: BackendComponent }. It was also necessary to add a / to the routerLink values (e.g. /backend instead of backend). Here's my final backend.routing.ts:
import { Routes, RouterModule } from '#angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
And backend.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
#NgModule({
imports: [ routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
welcome.component.ts:
import { Component } from '#angular/core';
#Component({
template: `
<h2>Welcome</h2>
<nav><a routerLink="backend">Login</a></nav>
`
})
export class WelcomeComponent { }
backend.component.ts
import { Component } from '#angular/core';
#Component({
template: `
<h2>Backend</h2>
<nav><a routerLink="welcome">Logout</a></nav>
`
})
export class BackendComponent { }
This resulted in the login button taking me to /backend and the logout button taking me to /welcome as expected. Here's a link to the plunk: Plunker

For angular 2 what do I need to have imported into my component for routerLink to work on my view

For angular 2 what do I need to have imported into my component for routerLink to work on my view?
I think I need to import something from my #angular/router? And then add it to my components directive?
But I'm not sure what that is.
You need ROUTER_DIRECTIVES, ROUTER_PROVIDERS
RouteConfig to configure routes and Router for navigation
Update : Routes for #angular/router
Source: https://angular.io/docs/ts/latest/guide/router-deprecated.html
Update Not sure if this you wanted! : https://i.imgsafe.org/55d36e1e91.png
main.ts
import { bootstrap } from '#angular/platform-browser-dynamic';
import { Component } from "#angular/core";
import { Routes, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '#angular/router';
import { Comp1 } from './comp1';
import { Comp2 } from './comp2';
import { Comp3 } from './comp3';
import { Comp4 } from './comp4';
import { Comp5 } from './comp5';
#Component( {
selector: 'root',
template: `<h1>ROOT Component</h1>
<a [routerLink]="['/comp1']" >Comp1 </a>
<a [routerLink]="['/comp2']" >Comp2 </a>
<a [routerLink]="['/comp3']" >Comp3 </a>
<a [routerLink]="['/comp4']" >Comp4 </a>
<a [routerLink]="['/comp5']" >Comp5 </a>
<router-outlet></router-outlet>
`,
directives: [ ROUTER_DIRECTIVES ], providers: [ ROUTER_PROVIDERS ]
} )
#Routes( [
{path: '/comp1', component: Comp1 },
{path: '/comp2', component: Comp2 },
{path: '/comp3', component: Comp3 },
{path: '/comp4', component: Comp4 },
{path: '/comp5', component: Comp5 }
] )
export class Root { }
bootstrap( Root );
compX.ts
import { Component } from "#angular/core";
#Component( {
selector: 'comp1',
template: `<h1>Child Component1</h1>
`
} )
export class Comp1 { }
You can refer to the documentation. There are constants - ROUTER_PROVIDERS and ROUTER_DIRECTIVES.
Ensure which router you want to use. Till beta version there was a version which is deprecated in RC1.

User Authentication before Appcomponent is loaded in Angular2

I have a simple application which loads material design Ui through Appcomponent. I need to Authenticate the user before the app component is loaded.
The app component is as follows
import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES,CanActivate} from 'angular2/router';
import {AuthHttp,AuthConfig, tokenNotExpired, AUTH_PROVIDERS} from 'angular2-jwt';
import {HomeComponent} from '../home/HomeComponent'
import {AboutComponent} from '../about/AboutComponent'
import {HeaderComponent} from './HeaderComponent'
import {LoginComponent} from '../login/LoginComponent'
import {AuthService} from '../../services/AuthService'
import {SidebarComponent} from './SidebarComponent'
import {DashboardComponent} from './DashboardComponent'
import {MDL} from './MaterialDesignLiteUpgradeElement';
#RouteConfig([
{path: 'app/home', component: HomeComponent, as: 'Home'},
{path: 'app/dashboard', component: DashboardComponent, as: 'Dashboard'},
{path: 'app/about', component: AboutComponent, as: 'About'},
{path: 'app/login', component: LoginComponent, as: 'Login'},
{path: 'app/*', redirectTo: ['Login']} // this redirect is not working for some reason
])
#Component({
selector: 'my-app',
/*template: '<router-outlet></router-outlet>',*/
template: `
<body>
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
<app-header mdl class="demo-header mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600"></app- header>
<app-sidebar class="demo-drawer mdl-layout__drawer mdl-color--blue-grey-900 mdl-color-text--blue-grey-50">
</app-sidebar>
<main class="mdl-layout__content mdl-color--grey-100">
<router-outlet></router-outlet>
</main>
</div>
<script src="https://code.getmdl.io/1.1.3/material.min.js"></script>
</body>
`,
/*styleUrls: ['../app/assets/styles.css'], */
directives: [ROUTER_DIRECTIVES,SidebarComponent,HeaderComponent,MDL],
providers: [AUTH_PROVIDERS,AuthService]
})
export class AppComponent {
constructor() {}
}
I have a login component which logs in the user as follows
import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {AuthHttp,AuthConfig, tokenNotExpired, AUTH_PROVIDERS} from 'angular2-jwt';
import {AuthService} from '../../services/AuthService'
#Component({
selector: 'protected',
template: '',
directives: [ROUTER_DIRECTIVES],
providers: [AUTH_PROVIDERS,AuthService]
})
export class LoginComponent {
constructor(private auth: AuthService) {
this.auth.login();
}
login() {
this.auth.login();
}
logout() {
this.auth.logout();
}
static loggedIn() {
return tokenNotExpired();
}
}
The login component uses the AuthService
AuthService
import {Injectable} from 'angular2/core';
import {ROUTER_DIRECTIVES, Router} from "angular2/router";
declare var Auth0Lock: any;
#Injectable()
export class AuthService {
constructor(private router: Router) {}
lock = new Auth0Lock('KEY','URL');
login() {
this.lock.show((error: string, profile: Object, id_token: string) => {
if (error) {
console.log(error);
return false;
}
localStorage.setItem('profile', JSON.stringify(profile));
localStorage.setItem('id_token', id_token);
this.router.navigate(['Home']);
});
}
logout() {
localStorage.removeItem('profile');
localStorage.removeItem('id_token');
}
}
I tried annotating the AppComponent with #CanActivate as follows
but that doesn't seems to be working as the AppComponent is loaded any how.
#CanActivate(() => LoginComponent.loggedIn())
export class AppComponent {
}
Any ideas how to prevent the appComponent from loading without authnetication ?
You could implement your own RouterOutlet which overrides the acitvate method to check, if the person is allowed to navigate to that route.
import {Directive, DynamicComponentLoader, ElementRef} from "angular2/core";
import {AuthService} from '../../services/AuthService'
import {Router, RouterOutlet, ComponentInstruction} from "angular2/router";
#Directive({
selector: 'auth-router-outlet'
})
export class AuthRouterOutlet extends RouterOutlet {
private _protectedRoutes = {
'app/home': true,
'app/dashboard': true,
'app/about': true
};
constructor(_elementRef: ElementRef, _loader: DynamicComponentLoader, private _router: Router, nameAttr: string, private _authService: AuthService) {
super(_elementRef, _loader, _router, nameAttr);
}
activate(nextInstruction: ComponentInstruction): Promise<any> {
if (this._protectedRoutes[nextInstruction.urlPath]) {
if (!this._authService.loggedIn()) {
this._router.navigate(['Login']);
}
}
return super.activate(nextInstruction);
}
}
In your AppComponent just replace the <router-outlet></router-outlet> with <auth-router-outlet></auth-router-outlet>.
For the redirect in your RouteConfig use two asterisks like this:
#RouteConfig([
{path: 'app/home', component: HomeComponent, as: 'Home'},
{path: 'app/dashboard', component: DashboardComponent, as: 'Dashboard'},
{path: 'app/about', component: AboutComponent, as: 'About'},
{path: 'app/login', component: LoginComponent, as: 'Login'},
{path: 'app/**', redirectTo: ['Login']} // two asterisks here
])

Resources