The new LoginComponent

From Solution Explorer, navigate to the /ClientApp/app/components/login/ folder and open the login.component.ts file; replace the current content with this brand-new login form:

<div class="login-container">
<img id="login-img" class="login-img"
src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" />
<h2 class="login-title">{{title}}</h2>
<form [formGroup]="form"
(ngSubmit)="onSubmit()"
class="login-form">
<div *ngIf="form.errors?.auth"
class="error-panel help-block">
{{form.errors.auth}}
</div>
<div class="form-group"
[ngClass]="{ 'has-error has-feedback' :
hasError('Username') }">
<input type="text" required
formControlName="Username"
class="form-control"
placeholder="Username or Email address" />
<span *ngIf="hasError('Username')"
class="glyphicon glyphicon-remove form-control-
feedback"
aria-hidden="true"></span>
<div *ngIf="hasError('Username')"
class="help-block">
Please insert a valid username or e-mail address.
</div>
</div>
<div class="form-group"
[ngClass]="{ 'has-error has-feedback' :
hasError('Password') }">
<input type="password" required
formControlName="Password"
class="form-control"
placeholder="Password" />
<span *ngIf="hasError('Password')"
class="glyphicon glyphicon-remove form-control-
feedback"
aria-hidden="true"></span>
<div *ngIf="hasError('Password')"
class="help-block">
Please insert a password.
</div>
</div>
<div class="checkbox">
<label><input type="checkbox" name="remember"
value="remember" />Remember me</label>
</div>
<button type="submit"
[disabled]="form.invalid"
class="btn btn-md btn-success btn-block btn-signin">
Sign in
</button>
</form>
<div class="login-link">
<a href="#">
Forgot the password?
</a>
</div>
</div>

The preceding source code resembles the other form-based templates, with a small difference: we added a validation message for the whole form, that will trigger in case of this.form.error?.auth. We'll understand it better in a short while, when we'll take a look at the TypeScript class file; for now, let's just take for granted that it will be shown whenever that error will be raised, making the form invalid.

Here's the login.component.ts class file (relevant lines are highlighted):

import { Component, Inject } from "@angular/core";
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { Router } from "@angular/router";
import { AuthService } from '../../services/auth.service';

@Component({
selector: "login",
templateUrl: "./login.component.html",
styleUrls: ['./login.component.css']
})

export class LoginComponent {
title: string;
form: FormGroup;

constructor(private router: Router,
private fb: FormBuilder,
private authService: AuthService,
@Inject('BASE_URL') private baseUrl: string) {

this.title = "User Login";

// initialize the form
this.createForm();

}

createForm() {
this.form = this.fb.group({
Username: ['', Validators.required],
Password: ['', Validators.required]
});
}

onSubmit() {
var url = this.baseUrl + "api/token/auth";
var username = this.form.value.Username;
var password = this.form.value.Password;

this.authService.login(username, password)
.subscribe(res => {
// login successful

// outputs the login info through a JS alert.
// IMPORTANT: remove this when test is done.
alert("Login successful! "

+ "USERNAME: "
+ username
+ " TOKEN: "
+ this.authService.getAuth()!.token
);

this.router.navigate(["home"]);
},
err => {
// login failed
console.log(err)
this.form.setErrors({
"auth": "Incorrect username or password"
});
});
}

onBack() {
this.router.navigate(["home"]);
}

// retrieve a FormControl
getFormControl(name: string) {
return this.form.get(name);
}

// returns TRUE if the FormControl is valid
isValid(name: string) {
var e = this.getFormControl(name);
return e && e.valid;
}

// returns TRUE if the FormControl has been changed
isChanged(name: string) {
var e = this.getFormControl(name);
return e && (e.dirty || e.touched);
}

// returns TRUE if the FormControl is invalid after user changes
hasError(name: string) {
var e = this.getFormControl(name);
return e && (e.dirty || e.touched) && !e.valid;
}
}

The highlighted lines show how we're using our new AuthService object instance--which we inject through DI--to attempt the login tasks and returning the result. Note that we also implemented a temporary JavaScript alert() to show the successful login information right before routing back the user to the Home view; we'll remove it as soon as we see that everything works as expected.

It's worth noting that the authService.login() method is returning an Observable with a value of true or false depending on result; by subscribing to that Observable, the LoginComponent class is able to tell how the login went and set the form.errors.auth value accordingly; that's precisely the error that will trigger the global validator message we configured earlier.

Last but not least, here's the new content of the LESS file. Note that we never added a login.component.less file to the project before, hence we'll have to create it from scratch:

.login-container {
max-width: 600px;
padding: 40px 40px;
background-color: #F7F7F7;
margin: 0 0 25px 0;
border-radius: 10px;
border: 1px solid #eee;

.login-img {
width: 96px;
height: 96px;
margin: 0 auto 10px;
display: block;
border-radius: 50%;
}

.login-title {
margin: 15px 0;
text-align: center;
font-size: 1.5em;
color: #444;
}

.login-link {
margin-top: 10px;
text-align: center;
}

.login-form {
.form-group {
margin-bottom: 8px;
}

.error-panel {
color: #e74c3c;
text-align: center;
}
}
}

@media (max-width: 767px) {
.login-container {
width: 100%;
}
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.61.218