src/app/register/register.component.ts
Allows the user to register for a Gropius account.
| selector | app-register |
| styleUrls | ./register.component.css |
| templateUrl | ./register.component.html |
Properties |
Methods |
constructor(fb: FormBuilder, apollo: Apollo, router: Router, registerUserMutation: RegisterUserGQL, userAvailablyQuery: CheckUsernameGQL, notify: UserNotifyService)
|
|||||||||||||||||||||
|
Defined in src/app/register/register.component.ts:21
|
|||||||||||||||||||||
|
Parameters :
|
| backToLogin | ||||||||
backToLogin(e: MouseEvent)
|
||||||||
|
Defined in src/app/register/register.component.ts:139
|
||||||||
|
Loads the login page.
Parameters :
Returns :
void
|
| resetForm | ||||||||
resetForm(e: MouseEvent)
|
||||||||
|
Defined in src/app/register/register.component.ts:126
|
||||||||
|
Resets form fields and marks all controls as pristine.
Parameters :
Returns :
void
|
| submitForm | ||||||||
submitForm(value: literal type)
|
||||||||
|
Defined in src/app/register/register.component.ts:100
|
||||||||
|
Given data needed for account creation and carries out the creation by issuing a mutation to the backend. If successfull, the user is redirected to the Login page.
Parameters :
Returns :
void
|
| validateConfirmPassword |
validateConfirmPassword()
|
|
Defined in src/app/register/register.component.ts:90
|
|
Recalculates the value and validation status of the password confirmation field. This is triggered whenever the user changes the password in the register form.
Returns :
void
|
| confirmValidator | ||||
Default value : () => {...}
|
||||
|
Defined in src/app/register/register.component.ts:73
|
||||
|
Checks that the password in the Confirm Password field matches the password in the Password field. |
||||
|
Parameters :
|
| isLoading |
Default value : false
|
|
Defined in src/app/register/register.component.ts:20
|
| publicClientName |
Default value : environment.publicClientName
|
|
Defined in src/app/register/register.component.ts:21
|
| userNameAsyncValidator | ||||
Default value : () => {...}
|
||||
|
Defined in src/app/register/register.component.ts:48
|
||||
|
Checks with backend to ensure that entered username is valid. A username is invalid when its taken or contains symbols like '*', etc. control is not a valid username. Emits null when username is valid |
||||
|
Parameters :
|
| validateForm |
Type : FormGroup
|
|
Defined in src/app/register/register.component.ts:19
|
import {Component} from '@angular/core';
import {FormBuilder, FormControl, FormGroup, ValidationErrors, Validators} from '@angular/forms';
import {Apollo} from 'apollo-angular';
import {Observable, Observer} from 'rxjs';
import {environment} from '@environments/environment';
import {CheckUsernameGQL, RegisterUserGQL, RegisterUserInput} from 'src/generated/public-graphql';
import {Router} from '@angular/router';
import {UserNotifyService} from '@app/user-notify/user-notify.service';
/**
* Allows the user to register for a Gropius account.
*/
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent {
validateForm: FormGroup;
isLoading = false;
publicClientName = environment.publicClientName;
constructor(
private fb: FormBuilder,
private apollo: Apollo,
private router: Router,
private registerUserMutation: RegisterUserGQL,
private userAvailablyQuery: CheckUsernameGQL,
private notify: UserNotifyService
) {
this.registerUserMutation.client = this.publicClientName;
this.userAvailablyQuery.client = this.publicClientName;
this.validateForm = this.fb.group({
username: ['', [Validators.required], [this.userNameAsyncValidator]],
email: ['', [Validators.email, Validators.required]],
password: ['', [Validators.required]],
confirm: ['', [this.confirmValidator]]
});
}
/**
* Checks with backend to ensure that entered username is valid.
* A username is invalid when its taken or contains symbols like '*', etc.
* @param control - Username that is handled.
* @returns Observable emitting values indicating error when string entered in
* control is not a valid username. Emits null when username is valid
*/
userNameAsyncValidator = (control: FormControl): Observable<any> =>
new Observable((observer: Observer<ValidationErrors | null>) => {
this.userAvailablyQuery.fetch({username: control.value}).subscribe(
({data}) => {
// case: username already taken
// => marks event as error
if (!data.checkUsername) {
// returns `{error: true}` to mark event as an error
observer.next({error: true, duplicated: true});
} else {
observer.next(null);
}
observer.complete();
},
(error) => {
this.notify.notifyError('Failed to verify user name!', error);
}
);
});
/**
* Checks that the password in the Confirm Password field
* matches the password in the Password field.
* @param control Password that is handled.
*/
confirmValidator = (control: FormControl): {[s: string]: boolean} => {
// case: no password given
if (!control.value) {
return {error: true, required: true};
}
// case: password does not match
else if (control.value !== this.validateForm.controls.password.value) {
return {confirm: true, error: true};
}
return {};
};
/**
* Recalculates the value and validation status of the password confirmation field.
* This is triggered whenever the user changes the password in the register form.
*/
validateConfirmPassword(): void {
setTimeout(() => this.validateForm.controls.confirm.updateValueAndValidity());
}
/**
* Given data needed for account creation
* and carries out the creation by issuing a mutation to the backend.
* If successfull, the user is redirected to the Login page.
* @param value - Data (from the register form) that is handled.
*/
submitForm(value: {username: string; email: string; password: string; confirm: string}): void {
for (const key of Object.keys(this.validateForm.controls)) {
this.validateForm.controls[key].markAsDirty();
this.validateForm.controls[key].updateValueAndValidity();
}
const input: RegisterUserInput = {
username: value.username,
displayName: value.username,
password: value.password,
email: value.email
};
this.registerUserMutation.mutate({input}).subscribe(
() => {
this.router.navigate(['login']);
},
(error) => {
this.notify.notifyError('Failed to register the user!', error);
}
);
}
/**
* Resets form fields and marks all controls as pristine.
* @param e - Event affecting the form reset.
*/
resetForm(e: MouseEvent): void {
e.preventDefault();
this.validateForm.reset();
for (const key of Object.keys(this.validateForm.controls)) {
this.validateForm.controls[key].markAsPristine();
this.validateForm.controls[key].updateValueAndValidity();
}
}
/**
* Loads the login page.
* @param e - Event affecting the form reset.
*/
backToLogin(e: MouseEvent): void {
e.preventDefault();
this.router.navigate(['login']);
}
}
<!--Register page-->
<div class="canvas-background">
<div class="form-container">
<div class="logo-wrapper">
<!-- Logo-->
<div class="logo-container">
<div class="logo-image">
<img src="../../assets/Gropius.png" alt="CCIMS-Logo" height="80" />
</div>
</div>
<div class="headline">
<h2>Register</h2>
</div>
</div>
<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm(validateForm.value)">
<!-- Username form item-->
<nz-form-item>
<nz-form-label [nzSpan]="7" nzRequired> Username </nz-form-label>
<nz-form-control [nzSpan]="12" nzHasFeedback nzValidatingTip="Validating..." [nzErrorTip]="userErrorTpl">
<input nz-input formControlName="username" placeholder="" />
<ng-template #userErrorTpl let-control>
<ng-container *ngIf="control.hasError('required')"> Please enter a Username! </ng-container>
<ng-container *ngIf="control.hasError('duplicated')"> This Username is taken! </ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<!-- Email form item-->
<nz-form-item>
<nz-form-label [nzSpan]="7" nzRequired> Email </nz-form-label>
<nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="emailErrorTpl">
<input nz-input formControlName="email" placeholder="" type="email" />
<ng-template #emailErrorTpl let-control>
<ng-container *ngIf="control.hasError('email')"> Please enter a valid Email! </ng-container>
<ng-container *ngIf="control.hasError('required')"> Please enter your Email! </ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<!-- Password form item-->
<nz-form-item>
<nz-form-label [nzSpan]="7" nzRequired> Password </nz-form-label>
<nz-form-control [nzSpan]="12" nzHasFeedback nzErrorTip="Please enter a Password">
<input nz-input type="password" formControlName="password" (ngModelChange)="validateConfirmPassword()" />
</nz-form-control>
</nz-form-item>
<!-- Confirm Password form item-->
<nz-form-item>
<nz-form-label [nzSpan]="7" nzRequired> Confirm Password </nz-form-label>
<nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="passwordErrorTpl">
<input nz-input type="password" formControlName="confirm" placeholder="" />
<ng-template #passwordErrorTpl let-control>
<ng-container *ngIf="control.hasError('required')"> Please enter your Password! </ng-container>
<ng-container *ngIf="control.hasError('confirm')"> Passwords do not match! </ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<!-- Buttons form item-->
<nz-form-item>
<nz-form-control [nzOffset]="7" [nzSpan]="12">
<button nz-button nzType="primary" [disabled]="!validateForm.valid">Register</button>
<button nz-button (click)="resetForm($event)">Reset</button>
<button nz-button (click)="backToLogin($event)">Back</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
</div>
./register.component.css
[nz-form] {
max-width: 600px;
}
button {
margin-left: 8px;
}