please look image description hereI need to create a multi step form without using Angular UI Router & angular material.
could any one help me.
<div class="wizard">
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/information-form']" [routerLinkActiveOptions]="{exact: true}">
Submit Information
</a>
<a [class.disabled]="idTab" routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/id-form']" [routerLinkActiveOptions]="{exact: false}">
Submit Id
</a>
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/verify-identity']" [routerLinkActiveOptions]="{exact: false}">
Verify Identity
</a>
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/final-validation']" [routerLinkActiveOptions]="{exact: false}">
Final Validation
</a>
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/approval']" [routerLinkActiveOptions]="{exact: false}">
Approval
</a>
</div>
working CodesandBox
app.component.html
<div>
<span class="state-container" [ngStyle]="state === 1 && {'color': 'red'}"
>state 1</span
>
<span class="state-container" [ngStyle]="state === 2 && {'color': 'red'}"
>state 2</span
>
<span class="state-container" [ngStyle]="state === 3 && {'color': 'red'}"
>state 3</span
>
</div>
<div *ngIf="state === 1">
<form #f1="ngForm" (ngSubmit)="onSubmit(user)" novalidate>
<label for="name">Name</label>
<input name="name" id="name" [(ngModel)]="user.name" />
<label for="family">Family</label>
<input name="family" id="family" [(ngModel)]="user.family" />
<button (click)="next(user)">Next</button>
</form>
</div>
<div *ngIf="state === 2">
<form #f2="ngForm" (ngSubmit)="onSubmit(user)" novalidate>
<label for="address">Address</label>
<input name="address" id="family" [(ngModel)]="user.address" />
<button (click)="back()">Back</button>
<button (click)="next(user)">Next</button>
</form>
</div>
<div *ngIf="state === 3">
<p>The End</p>
<button (click)="back()">Back</button>
<button (click)="reset()">Reset</button>
<button (click)="save(user)">Save</button>
</div>
app.component.ts
import { Component, OnInit } from "#angular/core";
interface User {
name: string;
family: string;
address: string;
}
#Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
title = "CodeSandbox";
state = 1;
user: User;
ngOnInit() {
this.user = {
name: "",
family: "",
address: ""
};
}
save(user: User) {
alert("Final Result:\n\n" + JSON.stringify(user));
}
next(user: User) {
++this.state;
alert(JSON.stringify(user));
}
back() {
--this.state;
}
reset() {
this.state = 1;
this.user = {
name: "",
family: "",
address: ""
};
}
}
app.module.ts
import { BrowserModule } from "#angular/platform-browser";
import { NgModule } from "#angular/core";
import { AppComponent } from "./app.component";
import { FormsModule } from "#angular/forms";
#NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
I personally don't recommend this approach. Just remember, If you don't save the data and refresh the page your data is gone.
Related
I have angular in front end and node.js in back end
I used angular material form stepper, it has 3 forms form1, form2, form3 for each step, on the last step
I need to join all objects in to one and post it to Node.js, I am new any help will be appreciated thanks.
bellow is my code:
<mat-horizontal-stepper linear #stepper>
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup" #personalInfo="ngForm" (ngSubmit)="form1()">
<ng-template matStepLabel>Personal Information</ng-template>
<mat-form-field>
<input matInput placeholder="Surname/Family name" formControlName="lastnameCtrl" required>
</mat-form-field>
<br />
<mat-form-field>
<input matInput placeholder="First name" formControlName="firstnameCtrl" required>
</mat-form-field>
<br />
<mat-form-field>
<mat-label>Gender</mat-label>
<mat-select [formControl]="genderControl" required>
<mat-option></mat-option>
<mat-option *ngFor="let gender of genders" [value]="gender">
{{gender.value}}
</mat-option>
</mat-select>
<mat-error *ngIf="genderControl.hasError('required')">Please choose gender</mat-error>
</mat-form-field>
<div>
<!-- <button [disabled]="personalInfo.invalid" mat-raised-button color="warn" matStepperNext type="submit" >Save & continue</button> -->
<button mat-raised-button color="primary" matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="secondFormGroup" [optional]="isOptional">
<form [formGroup]="secondFormGroup" #programAvailability="ngForm" (ngSubmit)="form2()">
<ng-template matStepLabel>Program Availability</ng-template>
<mat-form-field>
<input matInput placeholder="Email" formControlName="emailCtrl" required>
</mat-form-field>
<div>
<button mat-raised-button matStepperPrevious>Back</button>
<button mat-raised-button color="primary" matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step>
<form [formGroup]="thirdFormGroup" #programAvailability="ngForm" (ngSubmit)="form3()">
<ng-template matStepLabel>Confirm & submit</ng-template>
<mat-checkbox formControlName="agreementCtrl" (change)="changeCheck($event)"> I agree to....</mat-checkbox>
<div>
<button mat-raised-button matStepperPrevious>Back</button>
<button mat-raised-button [disabled]="disabledAgreement" color="primary" matStepperNext type="submit" >Submit</button>
<button mat-raised-button color="warn" (click)="stepper.reset()">Reset</button>
</div>
</form>
</mat-step>
and my component code is here:
import { Component, OnInit} from '#angular/core';
import { merge } from 'rxjs';
import {FormBuilder,FormControl, FormGroup, Validators} from '#angular/forms';
import{AgentService} from '../../services/agent.service';
import {PersonalData,ContactRequest, Agent} from '../../models/applicant.model';
import {ApplicantService} from '../../services/applicant.service';
#Component({
selector: 'app-manage-agent',
templateUrl: './manage-agent.component.html',
styleUrls: ['./manage-agent.component.css']
})
export class ManageAgentComponent implements OnInit {
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
thirdFormGroup:FormGroup;
selectedValue: string;
isEditable = false;
constructor(private agentService:AgentService,private _formBuilder: FormBuilder,private service:ApplicantService) { }
genderControl = new FormControl('', [Validators.required]);
genders: Gender[] = [
{value: 'Male', viewValue: 'Male'},
{value: 'Female', viewValue: 'Female'}
];
ngOnInit() {
//this.agentService.getNode();
this.firstFormGroup = this._formBuilder.group({
lastnameCtrl: ['', Validators.required],
firstnameCtrl: ['', Validators.required]
//genderCtrl: ['', Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
emailCtrl: ['', Validators.required]
});
this.thirdFormGroup = this._formBuilder.group({
agreementCtrl: ['', Validators.required]
});
}
disabledAgreement: boolean = true;
changeCheck(event){
this.disabledAgreement = !event.checked;
}
form1(){
console.log(this.firstFormGroup.value);
}
form2(){
console.log(this.secondFormGroup.value);
}
form3(){
if(this.firstFormGroup.valid && this.secondFormGroup.valid && this.thirdFormGroup.valid){
console.log('----form is valid----');
console.log(this.firstFormGroup.value);
console.log(this.secondFormGroup.value);
console.log(this.thirdFormGroup.value);
const f1 = this.firstFormGroup.value;
const f2 = this.secondFormGroup.value;
const f3 = this.thirdFormGroup.value;
if(this.service.formData.Id==0){
this.insertRecord(form);
}
//---------Update Record---------//
else{
this.UpdateRecord(form);
this.resetForm();
}
}else{
console.log('--- form is invalid');
}
}
You can merge values from forms at the moment you are "commiting" the changes.
if(this.firstFormGroup.valid && this.secondFormGroup.valid && this.thirdFormGroup.valid){
const result = Object.assign({}, this.firstFormGroup.value, this.secondFormGroup.value, this.thirdFormGroup.value);
if(this.service.formData.Id==0){
this.insertRecord(result);
} else {
this.UpdateRecord(result);
this.resetForm();
}
}else{
console.log('--- form is invalid');
}
When I imported this "import { FormsModule } from '#angular/forms';" on my angular project. it seems that my button is not working anymore. if I click on it there's nothing.
This is my app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
#NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
This is My Home HTML
the button class is btn
<div class="container color-dark">
<div class="col">
<p>Add you Bucket List</p>
</div>
<div class="col">
<p>Your Bucket List ({{ itemCount }})</p>
</div>
</div>
<div class="container color-light">
<div class="col">
<p>Use this form to add a new Bucket List!</p>
<form>
<input type="text" class="txt" name="item" placeholder="Life Goal.." [(ngModel)]="goalText">
<input type="submit" class="btn" value="Add Item" (click)="addItem()">
</form>
</div>
<div class="col">
<p class="life.container">
I want to climb a mountain.
</p>
</div>
</div>
This is My home.compenent.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
itemCount: number;
btnText: string = 'Add an Item';
goalText: string = 'My First Life Goal';
goals = [];
constructor() { }
ngOnInit() {
this.itemCount = this.goals.length;
}
additem(){
this.goals.push(this.goalText);
this.goalText = '';
this.itemCount = this.goals.length;
}
}
I tried searching it on google but nothing pops up or am I just looking at the wrong side of the code. if you have an idea or tips that can help me solve this, I would really appreciate it
in home.components.ts correct the function name from additem() to addItem() it will work . capital I should be used that's why it's not working
I have component that i want to inject into modal window using ng bootstrap features so i have imported modules into app also added into entrypoints as suggested in ng-bootstrap docs its giving me little hard time. what is correct approach basically i am calling modal from existing component and that component content should load into modal window. any help will be appreciate.
modal.component.ts
import {Component, Input} from '#angular/core';
import {NgbModal, NgbActiveModal} from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'ngbd-modal-content',
template: `
<div class="modal-header">
<h4 class="modal-title">Hi there!</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Hello, {{name}}!</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
`
})
export class NgbdModalContent {
#Input() name;
constructor(public activeModal: NgbActiveModal) {}
}
detail.component.ts
import { Component, OnInit,Pipe, PipeTransform, EventEmitter,Input, Output,OnChanges, SimpleChanges } from '#angular/core';
import {NgbModal,NgbActiveModal} from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.css'],
})
export class DetailComponent implements OnChanges{
constructor(private detailService: DetailService,private ngbModal: NgbModal) {};
onClick(evt){
const modalRef = this.ngbModal.open(Component);
}
}
detail.component.html
<div class="card card-outline-info">
<div class="card-header bg-info"><h5>Detail</h5><button (click)="onClick($event)"></button></div>
<div class="card-block">
<div class="table-responsive" style="cursor: pointer">
<generic-table [gtClasses]="'table-hover'" #myCustomTable [gtSettings]="secondConfigObject.settings" [gtFields]="secondConfigObject.fields" [gtData]="secondConfigObject.data"></generic-table>
</div>
</div>
</div>
app.module.ts
import { NgbModule,NgbActiveModal } from '#ng-bootstrap/ng-bootstrap';
import { NgbdModalContent } from './NgModal/modal.component';
#NgModule({
declarations: [
AppComponent,
StreamComponent,
SearchComponent,
DetailComponent,
SlaChartComponent,
NgbdModalContent
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
HttpModule,
ChartsModule,
BrowserAnimationsModule,
NgbModule.forRoot()
],
providers: [StreamService,DatePipe,
SearchService,
DetailService,
ChartService,AuthService,NgbActiveModal,
{provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi: true}],
entryComponents: [NgbdModalContent,DetailComponent],
bootstrap: [AppComponent]
})
Try this, I'm not a fan of your modal.component.ts file so scrap that and remove the NgbdModalContent from your app.module.ts
yourModal.component.html
<ng-template #theModal let-c="close" let-d="dismiss">
<div class="modal-header">
<h4 *ngIf="type == 0" class="modal-title">Header</h4>
<button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Hello, {{name}}!</p>
</div>
<div class="modal-footer">
<button type="button" id="cancel-edit-btn" class="btn btn-primary" (click)="c('Close click')">Cancel</button>
</div>
</ng-template>
yourModal.component.ts
import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ViewChildren, ElementRef, Renderer2 } from '#angular/core';
import { NgbModal } from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'app-custom-modal',
templateUrl: './yourModal.component.html',
styleUrls: ['./yourModal.component.scss']
})
export class EditNotesComponent implements OnInit {
#Input() name: string;
#ViewChild('theModal') theModal: ElementRef;
constructor(private modalService: NgbModal) {}
ngOnInit() {
}
showModal() {
this.modalService.open(this.theModal, { size: 'sm', backdrop: 'static'});
}
}
detail.component.html
<div class="card card-outline-info">
<div class="card-header bg-info"><h5>Detail</h5><button (click)="yourCustomModal.showModal()"></button></div>
<div class="card-block">
<div class="table-responsive" style="cursor: pointer">
<generic-table [gtClasses]="'table-hover'" #myCustomTable [gtSettings]="secondConfigObject.settings" [gtFields]="secondConfigObject.fields" [gtData]="secondConfigObject.data"></generic-table>
</div>
</div>
</div>
<app-custom-modal #yourCustomModal [name]="name"></app-custom-modal>
detail.component.ts
import { Component, OnInit,Pipe, PipeTransform, EventEmitter,Input, Output,OnChanges, SimpleChanges } from '#angular/core';
#Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.css'],
})
export class DetailComponent implements OnChanges{
name: string;
constructor(private detailService: DetailService) {
this.name = 'John Doe';};
}
I have a Stepper from #Angular/Material and it looks great. However, I see many example that have only the current step opened up. I would like this functionality. All inactive steps should be closed.
[EDIT]: Just added in the HTML and TS file.
Component HTML File
<img width="350px" align="middle" mat-card-image src="../assets/Icon_Rev8.png" alt="Logo">
<mat-card-content>
<mat-tab-group mat-stretch-tabs [selectedIndex]="0" dynamicHeight=true>
<mat-tab label="Login">
<form>
<mat-form-field class="sameWidth">
<input matInput style="width:100%;" placeholder="Username">
</mat-form-field>
<mat-form-field class="sameWidth">
<input matInput style="width:100%;" placeholder="Password">
</mat-form-field>
</form>
<button class="sameWidth" mat-raised-button color="primary">Login</button>
<button class="sameWidth" mat-button color="primary">Forgot Password?</button>
</mat-tab>
<mat-tab label="Register">
<mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
<mat-vertical-stepper [linear]=true>
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Fill out your name</ng-template>
<mat-form-field>
<input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [active]="true" [stepControl]="secondFormGroup">
<form [formGroup]="secondFormGroup">
<ng-template matStepLabel>Fill out your address</ng-template>
<mat-form-field>
<input matInput placeholder="Address" formControlName="secondCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
You are now done.
<div>
<button mat-button matStepperPrevious>Back</button>
</div>
</mat-step>
</mat-vertical-stepper>
<!--<form>
<table cellspacing="0">
<tr>
<td>
<mat-form-field>
<input style="width: 40%;" matInput placeholder="First Name">
</mat-form-field>
</td>
<td>
<mat-form-field>
<input style="width: 40%;" matInput placeholder="Last name">
</mat-form-field>
</td>
</tr>
</table>
<mat-form-field style="width:100%;">
<input matInput placeholder="Password">
</mat-form-field>
</form>-->
<mat-checkbox style="z-index: 1000;" color="primary">I Agree to the Terms and Conditions</mat-checkbox>
<button class="sameWidth" mat-raised-button color="primary">Register</button>
</mat-tab>
</mat-tab-group>
</mat-card-content>
Component TS File
import { Component, OnInit, ViewEncapsulation, Inject } from "#angular/core";
import {
MatIconRegistry,
MatDialog,
MatDialogRef,
MAT_DIALOG_DATA
} from "#angular/material";
import { DomSanitizer } from "#angular/platform-browser";
import { HttpClientModule, HttpClient } from "#angular/common/http";
import { FormBuilder, FormGroup, Validators } from "#angular/forms";
#Component({
selector: "app-login",
templateUrl: "login.component.html",
styleUrls: ["login.component.css"]
})
export class LoginComponent {
animal: string;
name: string;
constructor(
private _formBuilder: FormBuilder,
iconRegistry: MatIconRegistry,
sanitizer: DomSanitizer,
public dialog: MatDialog
) {
iconRegistry.addSvgIcon(
"close",
sanitizer.bypassSecurityTrustResourceUrl(
"assets/icons/ic_close_48px.svg"
)
);
}
openDialog(): void {
let dialogRef = this.dialog.open(LoginDialogComponent, {
width: "400px",
data: { name: this.name, animal: this.animal }
});
dialogRef.afterClosed().subscribe(result => {
console.log("The dialog was closed");
this.animal = result;
});
}
}
#Component({
selector: "dialog-login",
templateUrl: "loginDialog.component.html",
styleUrls: ["loginDialog.component.css"]
})
export class LoginDialogComponent {
constructor(
private _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<LoginDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any
) {}
onNoClick(): void {
this.dialogRef.close();
}
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
firstCtrl: ["", Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
secondCtrl: ["", Validators.required]
});
}
}
My Current Status:
My Goal:
There is no official fix yet. I have submitted a bug-report and it is being looked into. For now I have researched and found a workaround for this issue. I had to add (selectionChange)="cambiaStep($event)" as an attribute to my <mat-vertical-stepper> tag. Then I had to add a <ng-container> under all of my <mat-step> tags. In each corresponding <ng-container>, I had to set an attribute based on which position it had in the stepper order. In each <ng-container> I had to add *ngIf="stepIndex === 0" but the 0 was based on its order in the steps (0: first, 1: second, 2: third, etc.)
My stepper ended up having code as such:
<mat-vertical-stepper (selectionChange)="cambiaStep($event)">
<mat-step>
<ng-container *ngIf="stepIndex === 0">
</ng-container>
</mat-step>
<mat-step>
<ng-container *ngIf="stepIndex === 1">
</ng-container>
</mat-step>
<mat-step >
<ng-container *ngIf="stepIndex === 2">
</ng-container>
</mat-step>
</mat-vertical-stepper>
I also had to add the event function in my component's *.ts file.
export class LoginDialogComponent {
stepIndex: number = 0;
cambiaStep(e) {
this.stepIndex = e.selectedIndex;
}
constructor() {}
}
I just copy pasted your code in default angular-material stepper code and it's showing like your goal
https://stackblitz.com/edit/angular-tpeo6s?embed=1&file=app/stepper-overview-example.html
Edit
It seems angular material bug to me.
if stepper is put out of tabs, it is working but inside tab, though aria-expanded="false" for inactive steps , material is not adding style="height: 0px; visibility: hidden;" to hide inactive steps.
you can log issues related to angular material 2 HERE
I'm having an issue with doing a redirect following a form submission for logging in on Angular 2. The application performs a full reload on the redirect to dashboard. I have checked several posts on stack overflow & other blogs, with no luck. This is the closest one; However, there is no answer on the thread. See my code below.
After I press the login, the page loads, and then reloads again. The URL is also changing to put the query string in the URL, which I suspect is causing the issue. How can I fix this issue? I suspect is has something to do with the way my form is set up.
auth.component.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { NgForm, FormBuilder, Validators } from '#angular/forms';
import { Router } from '#angular/router';
import { User } from '../shared/user';
declare var Materialize:any;
import { AuthService } from '../shared/services/auth.service';
#Component({
moduleId: module.id,
selector: 'logon',
templateUrl: 'auth.component.html',
})
export class AuthComponent implements OnInit {
currentUser = new User(null, '', '', '', '', 'vistor');
submitted = false;
authForm: NgForm;
#ViewChild('authForm') currentForm: NgForm;
constructor(
private router: Router,
public authService: AuthService
) { }
ngOnInit(): void {
}
onSubmit() {
this.submitted = true;
this.authService.login(this.currentUser).then(response => {
if (response) {
this.goToDashboard();
} else {
var toastContent = '<span><b>Invalid email or password!</b></span>';
Materialize.toast(toastContent, 5000, 'red');
}
});
}
goToDashboard() {
this.router.navigate(['dashboard']);
}
}
auth.component.html
<div class="container">
<div class="card">
<div class="card-content">
<span class="card-title">Logon</span>
<form materialize #authForm="ngForm" class="col s12">
<div class="input-field col s12">
<input required class="validate" id="email" type="email" name="email" [(ngModel)]="currentUser.email" #email="ngModel" validate="email">
<label for="email" data-error="Invalid Email">Email</label>
</div>
<div class="input-field col s12">
<input required class="validate" id="password" type="password" name="password" [(ngModel)]="currentUser.password" #password="ngModel" validate="password">
<label for="password" data-error="Invalid Password">Password</label>
</div>
<div class="card-action">
<button [disabled]="!authForm.form.valid" (click)="onSubmit()" class="btn orange darken-1 waves-effect waves-light" type="submit">Log In
<i class="material-icons right">send</i>
</button>
</div>
</form>
</div>
</div>
</div>
Angular 2 Routes
const routes: Routes = [
{ path: '', redirectTo: '/auth', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'spelling', component: SpellingComponent },
{ path: 'definition', component: DefinitionComponent },
{ path: 'auth', component: AuthComponent },
{ path: '**', redirectTo: '/dashboard', pathMatch: 'full' }
];
Don't use the type as submit in Angular Single Page applications. The reason might be
<button [disabled]="!authForm.form.valid" (click)="onSubmit()" class="btn orange darken-1 waves-effect waves-light" type="submit">Log In
<i class="material-icons right">send</i>
</button>
Try using
<button [disabled]="!authForm.form.valid" (click)="onSubmit()" class="btn orange darken-1 waves-effect waves-light" type="button">Log In
<i class="material-icons right">send</i>
</button>
Angular 2 needs an order in paths to show the correct routing, I think the solution is related with the order of paths. For example, you can try this:
const routes: Routes = [
{ path: '', redirectTo: '/auth', pathMatch: 'full' },
{ path: 'auth', component: AuthComponent },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'spelling', component: SpellingComponent },
{ path: 'definition', component: DefinitionComponent },
{ path: '**', redirectTo: '/dashboard' }
];
and
goToDashboard() {
this.router.navigate(['dashboard/']);
}