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
Related
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
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]
})
What the webpage looks like
So I am trying to make a dropdown but when the dropdown is clicked it displays not overlapping the other input, but at the bottom of the screen.
Here is the relevant chunk of HTML code:
<div class="form-row">
<!-- Grid column -->
<div class="col-md-6">
<mat-form-field>
<mat-label>Toppings</mat-label>
<mat-select [formControl]="toppings" multiple>
<mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<!-- Grid column -->
<!-- Grid column -->
<div class="col-md-6">
<!-- Material input -->
<div class="md-form form-group">
<input mdbInput type="password" class="form-control" id="inputPassword4MD" placeholder="John's Law Firm">
<label for="inputPassword4MD">Firm Name</label>
</div>
</div>
<!-- Grid column -->
</div>
<!-- Grid row -->
This is the relevant part of the ts file:
toppings = new FormControl();
toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
constructor() { }
And finally, this is my app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { AboutComponent } from './about/about.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { HomeComponent } from './home/home.component';
import {MatButtonModule,MatIconModule} from '#angular/material';
import { ContactComponent } from './contact/contact.component';
import { ServicesComponent } from './services/services.component';
import { ScheduleComponent } from './schedule/schedule.component';
import {MatInputModule} from '#angular/material/input';
import {FormsModule, ReactiveFormsModule} from '#angular/forms';
import {MatSelectModule} from '#angular/material/select';
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
AboutComponent,
HomeComponent,
ContactComponent,
ServicesComponent,
ScheduleComponent,
ContactComponent,
ServicesComponent,
ScheduleComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatButtonModule,
MatIconModule,
MatInputModule,
FormsModule,
ReactiveFormsModule,
MatSelectModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
You'll need an Angular material core theme in your styles.scss file. Just add this in styles.scss:
#import '#angular/material/prebuilt-themes/deeppurple-amber.css';
or whatever other themes you want. You'll need the core theme for components to act right and then you can create a custom theme if you don't like the core default colors.
I have a full working ASP.Net Zero application navigation working. Now I created an internal page I want to navigate, something like this:
With the following structure:
Content of test.component.html:
<div [#routerTransition]>
<div class="m-content">
<div class="m-portlet m-portlet--mobile tests">
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">Spellings</h3>
</div>
</div>
</div>
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
There I defined the <router-outlet> to navigate using the "Navigation Area" of the pic.
I created a custom routing navigation defined in spelling-routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { TestComponent } from './test-list/test.component';
import { QuestionComponent } from './questions/questions.component';
import { TestContainerComponent } from './test-list/test-container/test-container.component';
#NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: TestComponent,
children: [
{ path: 'test-container', component: TestContainerComponent, data: { permission: 'Pages.Tenant.Tests' } },
{ path: 'questions/:testId', component: QuestionComponent, data: { permission: 'Pages.Tenant.Tests' } }
]
}
])
],
exports: [
RouterModule
]
})
export class SpellingRoutingModule { }
This works to load the main test.component.html, but can't fill the <router-outlet> inside it to navigate to some inner Components.
Please, how to fill the <router-outlet> object of test.component.html with a default one?
See the src folder content here:
Dropbox link to src folder
I have a angular2 component:
import {Component} from '#angular/core';
#Component({
selector: 'sidenav',
templateUrl: './sidenav.html',
styleUrls: ['./sidenav.scss'],
})
export class SidenavComponent {
constructor() {
}
}
I want to include it in another component, which works fine except that the links don't work:
<li><a routerLink="/portfolio">Portfolio</a></li>
I include the component simply with the tag
<sidebar> </sidebar>
what is the missing part. I included the router but it didn't help.
I use the generated jhipster app and want to add a sidenav only for authorized Users. There are many modules and routes defined including each other, but I just don't find the right way.
I include the component simply with the tag
<sidebar> </sidebar>
Isn't it supposed to be <sidenav> </sidenav>?
Maybe u r not using RouterModule correctly?
RouterModule.forRoot(<urRouteDataStructure>)
this is the setting in the imports-array.
I am sharing my code below for reference:-
(I am using bootstrap 3.x)
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { ServerComponent } from './server/server.component';
...
...
import {Routes, RouterModule} from '#angular/router';
const appRoutes: Routes = [
{ path:'server',
component: ServerComponent
}
];
#NgModule({
declarations: [
AppComponent,
ServerComponent,
BasicHighlightDirective,
BetterHighlightDirective,
UnlessDirective
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(appRoutes)
],
providers: [LoggingService, AccountsService],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<div class="container">
<div class="row">
<div class="col-xs-12">
<ul class="nav nav-tabs">
<!-- <li role="presentation"> Server Comp </li> -->
<li role="presentation"><a routerLink="/server"> Server Comp </a> </li>
<li role="presentation"><a routerLink="/"> Home Comp</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<router-outlet></router-outlet>
</div>
</div>
</div>
Heres my output screenshot: