I am currently trying to submit a form. However, I am allowed to login only after clicking the submit button twice. I would like to know how to fix this please
Login page.html
<div >
<form [formGroup]="loginForm" (ngSubmit)="checkLogin()" autocomplete="disabled">
<div >
<label for="exampleInputEmail1">Email</label>
<input type="email" name="email" aria-describedby="emailHelp" placeholder="Enter email" formControlName="email" autocomplete="new-email">
</div>
<div >
<label for="exampleInputPassword1">Password</label>
<input type="password" placeholder="Password" formControlName="password">
</div>
<div *ngIf = "triedLogin == true && approvedLogin == false">
<span >Invalid E-mail or Password</span>
</div>
<button type="submit" [disabled]="!loginForm.valid">Submit</button>
</form>
</div>
Login component.ts
import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from '../authentication.service';
import { Validators } from '@angular/forms';
import { FormGroup, FormControl } from '@angular/forms';
import { Router } from '@angular/router';
import { SignInData } from '../Model/signinData';
@Component({
selector: 'app-login-page',
templateUrl: './login-page.component.html',
styleUrls: ['./login-page.component.css']
})
export class LoginPageComponent implements OnInit {
approvedLogin:boolean = false;
triedLogin: boolean = false;
loginForm = new FormGroup({
email : new FormControl('', Validators.compose([Validators.email, Validators.required])),
password : new FormControl('', Validators.compose([Validators.minLength(8), Validators.required]))
});
constructor(
private authentication: AuthenticationService,
private route: Router
) { }
ngOnInit(): void {
this.authentication.logout();
}
checkLogin()
{
this.triedLogin = true;
this.approvedLogin = this.getLoginResult();
if (this.approvedLogin)
{
this.route.navigate(['details']);
}
}
private getLoginResult(): boolean
{
var signindata = new SignInData(this.loginForm.value.email, this.loginForm.value.password);
return this.authentication.authenticate(signindata);
}
}
Authentication service, where I retrieve user details and checks for valid login credentials
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { SignInData } from './Model/signinData';
import { SharedService } from './shared.service';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
isAuthenticated: boolean = false;
employee:any;
private logins: any = [];
constructor(private router: Router, private service: SharedService) { }
ngOnInit(): void {
this.getLogins();
console.log(this.logins);
}
private getLogins()
{
this.service.getLoginDetails().subscribe(data =>
Object.assign(this.logins, data)
)
}
authenticate(signinData: SignInData): boolean
{
return this.checkCredentials(signinData);
}
private checkCredentials(signinData: SignInData): boolean
{
this.getLogins();
var found = false;
//Loop through each element to check for user login is correct
this.logins.forEach(element => {
console.log(this.logins);
if (found == false)
{
if (element.email == signinData.getEmail())
{
if (element.password == signinData.getPassword())
{
found = true;
}
}
}
});
return found;
}
logout()
{
this.isAuthenticated = false;
this.router.navigate(['']);
}
}
Shared services, where I am retrieving data from my RestAPI
import { Injectable } from '@angular/core';
import { HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SharedService {
readonly APIUrl = "https://localhost:*****/api/";
constructor(private http:HttpClient)
{ }
getLoginDetails():Observable<any[]>
{
return this.http.get<any>(this.APIUrl "Login/");
}
}
CodePudding user response:
Hope I know what happens,
into service you call ngOnInit(), but Angular Service don't have that live hooks, btw you should be implements they.
Thats mean on first click you dont have AuthenticationService.logins, then when you call checkCredentials(), AuthenticationService.logins is undefined, and you get your error.
How to solve it? Easiest way - copy into constructor
constructor(private router: Router, private service: SharedService) {
this.getLogins();
console.log(this.logins);
}
CodePudding user response:
Hi for double click you cannot use ngSubmit event binding on form.use dblclick event on button and capture that.
<div >
<form [formGroup]="loginForm" autocomplete="disabled">
<div >
<label for="exampleInputEmail1">Email</label>
<input type="email" name="email" aria-describedby="emailHelp" placeholder="Enter email" formControlName="email" autocomplete="new-email">
</div>
<div >
<label for="exampleInputPassword1">Password</label>
<input type="password" placeholder="Password" formControlName="password">
</div>
<div *ngIf = "triedLogin == true && approvedLogin == false">
<span >Invalid E-mail or Password</span>
</div>
<button type="submit" (dblclick)="checkLogin()" [disabled]="!loginForm.valid">Submit</button>
</form>
</div>
