lazy loading with routing in angular 9 - javascript

I try to do lazy loading with a login component.
So I have a AccountModule like this:
#NgModule({
declarations: [LoginComponent, RegisterComponent],
imports: [
CommonModule,
AccountRoutingModule
]
})
export class AccountModule { }
and my App-routing.module looks like this:
const routes: Routes = [
{path: 'account', loadChildren: () => import('./account/account.module')
.then(mod => mod.AccountModule)},
{ path: '**', redirectTo: 'not-found', pathMatch: 'full' }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
and the login component looks like this:
<div class="d-flex justify-content-center mt-5">
<div class="col-3">
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div class="text-center mb-4">
<h1 class="h3 mb-3 font-weight-normal">Login</h1>
</div>
<app-text-input formControlName="email" [label]="'Email Address'"></app-text-input>
<app-text-input formControlName="password" [label]="'Password'" [type]="'password'"></app-text-input>
<button [disabled]="loginForm.invalid" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div>
</div>
but so if I want to go to: http://localhost:4200/account/login. It goes back to http://localhost:4200.
So what I have to change?
Thank you
AccountRoutingModule:
const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: 'register', component: RegisterComponent}
];
#NgModule({
declarations: [],
imports: [
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AccountRoutingModule { }

You used RouterModule.forRoot in AccountRoutingModule which probably registers login and register to the root. You should only use forRoot in AppModule and RouterModule.forChild in others.

You just need to change in your AccountRoutingModule
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})

Related

Can't bind to 'formGroup' since it isn't a known property of 'form' just in logincomponent

I create a form using Angular ReactiveFormsModule but I got this error message when building the app
ERROR in src/app/security/login/login.component.html:11:13 - error NG8002: Can't bind to 'formGroup' since it isn't a known property of 'form'.
11 <form [formGroup]="loginForm" (ngSubmit)="loginProces()">
for LoginComponent.
I copied the same code in LogoutComponent (for testing) and no error in this component.The two components are in same module -security.
login.component.html:
<div class="wrapper fadeInDown">
<div id="formContent">
<!-- Tabs Titles -->
<!-- Icon -->
<div class="fadeIn first">
<img src="" id="icon" alt="User Icon" />
</div>
<!-- Login Form -->
<form [formGroup]="loginForm" (ngSubmit)="loginProces()">
<input type="text" id="login" class="fadeIn second" name="login" formControlName="username" placeholder="login">
<input type="text" id="password" class="fadeIn third" name="login" formControlName="password" placeholder="password">
<input type="submit" class="fadeIn fourth" value="Log In">
</form>
<!-- Remind Passowrd -->
<div id="formFooter">
<a class="underlineHover" href="#">Forgot Password?</a>
</div>
</div>
</div>
Login.component.ts
import { Component, OnInit } from '#angular/core';
import { FormControl, FormGroup, Validators } from '#angular/forms';
import { LoginService } from '../services/login.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
loginForm:FormGroup;
constructor(private authService: LoginService) { }
ngOnInit(): void {
this.initForm();
}
initForm(){
this.loginForm = new FormGroup({
username: new FormControl("",[Validators.required]),
password : new FormControl("",[Validators.required])
});
}
loginProces(){
if(this.loginForm.valid){
this.authService.login(this.loginForm.value).subscribe(result=>{
if(result.success){
console.log(result);
alert(result.message);
}else{
alert(result.message);
}
})
}
}
}
Security.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { LoginComponent } from './login/login.component';
import { LogoutComponent } from './logout/logout.component';
import { RegisterComponent } from './register/register.component';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#NgModule({
declarations: [
LoginComponent,
LogoutComponent,
RegisterComponent
],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
],
exports:[
]
})
export class SecurityModule { }
What am I doing wrong?
Routing.module
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { LoginComponent } from './security/login/login.component';
const routes: Routes = [
{path:'login', component : LoginComponent }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
It is possible that the old bundle is still being served. The changes has to be included in the bundle which is being served. Restart the server and check if this problem persists.
ng serve

Router outlet inside primary router outlet doesn't display anything with no errors

Cant seem to find what the issue is here as I'm getting no errors from Angular.
I am trying to get a router-outlet inside the primary router-outlet to display a component. Im correctly selecting the router but it is not showing the component i have selected in the second outlet.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: 'dashboard', loadChildren: () => import('./pages/dashboard/dashboard.module').then(m => m.DashboardModule) }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
dashboard-routing.module.ts
// ...
const routes: Routes = [
{ path: '', component: DashboardComponent },
{ path: 'forms', component: FormsComponent, outlet: 'sidebar' },
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class DashboardRoutingModule { }
dashboard.component.html
<app-header></app-header>
<mat-sidenav-container>
<mat-sidenav mode="side" opened>
<mat-nav-list>
<a mat-list-item [routerLink]="[{ outlets: { sidebar: ['forms'] } }]" routerLinkActive="active">Forms</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<main class="bfa-main">
<router-outlet name="sidebar"></router-outlet>
</main>
</mat-sidenav-content>
</mat-sidenav-container>
<app-footer></app-footer>
The routerlink is correctly selected and displays an active class, as well as a link too:
http://localhost:4200/dashboard/(sidebar:forms)
However there is nothing displayed here and no errors, when i am expecting to see the forms component inside the inner router outlet named sidebar
Does anyone know what I'm missing here?
Thanks
Decided to have the dashboard as a wrapper instead for each of the dashboard components using ng-content
<app-header></app-header>
<mat-sidenav-container>
<mat-sidenav mode="side" opened>
<mat-nav-list>
<a mat-list-item [routerLink]="['forms']" routerLinkActive="active">Forms</a>
<a mat-list-item [routerLink]="['users']" routerLinkActive="active">Users</a>
<a mat-list-item [routerLink]="['posts']" routerLinkActive="active">Posts</a>
<a mat-list-item [routerLink]="['pages']" routerLinkActive="active">Pages</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<main class="bfa-main">
<ng-content></ng-content>
</main>
</mat-sidenav-content>
</mat-sidenav-container>
<app-footer></app-footer>

Angular 4 Application Home Page not Showing Login screen

For one of the Angular 4 application that I'm working on, I have the following app.component.html:
<app-layout-header></app-layout-header>
<router-outlet></router-outlet>
<app-layout-footer></app-layout-footer>
This is my app.routing.ts:
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/index';
import { LoginComponent } from './login/index';
import { RegisterComponent } from './register/index';
import { AuthGuard } from './shared/index';
const appRoutes: Routes = [
{ path: '', component: HomeComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
The app.module.ts is:
import { BrowserModule } from '#angular/platform-browser';
import { ModuleWithProviders, NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import {
ApiService,
AuthGuard,
FooterComponent,
HeaderComponent,
JwtService,
ProfilesService,
SharedModule,
UserService
} from './shared';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { routing } from './app.routing';
#NgModule({
declarations: [
AppComponent,
FooterComponent,
HeaderComponent,
LoginComponent,
RegisterComponent,
],
imports: [
SharedModule,
BrowserModule,
routing
],
providers: [
ApiService,
AuthGuard,
JwtService,
ProfilesService,
UserService
],
bootstrap: [AppComponent]
})
export class AppModule { }
I want this bit of html (this is actually my login.component.html) to be displayed when the user access the application at http://localhost:4200/
<div class="auth-page">
<div class="container page">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>Login</h2>
<form name="form" (ngSubmit)="f.form.valid && login()" #f="ngForm" novalidate>
<div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" [(ngModel)]="model.username" #username="ngModel" required />
<div *ngIf="f.submitted && !username.valid" class="help-block">Username is required</div>
</div>
<div class="form-group" [ngClass]="{ 'has-error': f.submitted && !password.valid }">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel" required />
<div *ngIf="f.submitted && !password.valid" class="help-block">Password is required</div>
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">Login</button>
<img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
</div>
</form>
</div>
</div>
</div>
</div>
But strangely when I access the url http://localhost:4200, I see the following screen:
So there are two problems:
Why is the URL http://localhost:4200/#/ instead of http://localhost:4200/
What is wrong with what I'm doing so that I can get the Login html getting displayed?
Please help!
1) # is added properly due to your router configuration (useHash: true):
const rootRouting: ModuleWithProviders = RouterModule.forRoot([], { useHash: true });
2) To show LoginComponent you have to:
use redirectTo property of default path
or manually call routerService.navigateByUrl("/login") call from AppComponent or HomeComponent or AuthGuard

Error: Cannot match any routes. URL Segment: 'cmcwebapp'

I am using angular 4. My angular app works fine when I run it with "ng serve". That's when it run with context-root as "/".
My app need to compile with java webapp and is Deployed to servlet-container as part of war file. this app runs under context-root 'cmcwebapp'.
my index.html has element
<base href="/">
just under "head" element. and When I compile angular app I use command
ng build --base-href cmcwebapp
Once this compiles I copy contents of dist folder and paste it into java webapp and creates a war file.
when I run this on browser with "http://localhost:8080/cmcwebapp". all the javascript, css and images loads fine. the URL changes to "http://localhost:8080/cmcwebapp/cmcwebapp/" and I get this "Error: Cannot match any routes. URL Segment: 'cmcwebapp'".
I have this as my routes definition in app.module.ts
const appRoutes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'distribute', component: DistributeComponent },
{ path: 'consume', component: ConsumeComponent },
{ path: '', redirectTo: 'home', pathMatch: 'full'}
];
#NgModule({
declarations: [
AppComponent,
HomeComponent,
DistributeComponent,
ConsumeComponent
],
imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot(appRoutes),
WjGridModule
],
providers: [EppmService],
bootstrap: [AppComponent]
})
export class AppModule { }
and this is my app.component.html
<div class="menu">
<nav class="navbar navbar-inverse" style="overflow:hidden">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li routerLinkActive="active"><a routerLink="home">home</a></li>
<li routerLinkActive="active"><a routerLink="distribute">Distribute</a></li>
<li routerLinkActive="active"><a routerLink="consume">Consume</a></li>
</ul>
<div class="submission">
<button type="button" class="btn btn-primary">Submit</button>
</div>
</div>
</nav>
</div>
<div class="container-fluid">
<router-outlet></router-outlet>
</div>
I am not able to figure out where I am going wrong

Angular2 attribute directive does not work in components rendered in RouterOutlet?

I have been using NG2 since the final release 2.0.2 now 2.4.1. Attribute Directives work in simple case like what in the tutorial at https://angular.io/docs/ts/latest/guide/attribute-directives.html, and all tutorials I could find are also with simple case of rendering the directive declared immediately in app.component.html. However, I have components rendered in router outlet as defined in app.component.html like this:
<nav>
<a routerLink="/" routerLinkActive="active"> </a>
</nav>
<div class="jumbotron">
<div class="container">
<div class="col-sm-12">
<router-outlet></router-outlet>
</div>
</div>
</div>
And I declare the directive in app.module.ts:
#NgModule({
...
declarations: [
//** Root level components
AppComponent,
HomeComponent,
...
HighlightDirective,
],
And the feature modules with routes are declared in app-routing.module.ts:
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'ml_payment', loadChildren: 'app/payment/payment.module#PaymentModule', canActivate: [AuthGuard] },
{ path: 'account', loadChildren: 'app/account/account.module#AccountModule', canActivate: [AuthGuard, AdminGuard] },
{ path: 'wip', component: WIPComponent },
{ path: '', component: HomeComponent, canActivate: [AuthGuard] },
{ path: '**', component: NotFoundComponent },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
When the nested components are rendered, NG2 runtime do not render myHighlight into respective style tag of HTML. I just wonder if I had missed something or NG2 custom attribute directives do not work with RouterOutlet?
use routerLinkActive as [routerLinkActive]="['active']"
<nav>
<a routerLink="/" [routerLinkActive]="['active']"> </a>
</nav>
<div class="jumbotron">
<div class="container">
<div class="col-sm-12">
<router-outlet></router-outlet>
</div>
</div>
</div>
#ZZZ, did you put the directive in the "exports" section of the module where it was declared? Today I had a similar issue when I forgot to export a directive.
Good luck.

Categories