How to make angular submit fire only once?

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 class="central-form">
    <form class="login-form" [formGroup]="loginForm" (ngSubmit)="checkLogin()" autocomplete="disabled">
            <div class="form-group">
                <label for="exampleInputEmail1">Email</label>
                <input type="email" class="form-control" name="email" aria-describedby="emailHelp" placeholder="Enter email" formControlName="email" autocomplete="new-email">
            </div>

            <div class="form-group">
                <label for="exampleInputPassword1">Password</label>
                <input type="password" class="form-control" placeholder="Password" formControlName="password">
            </div>
            
            <div class="form-group" *ngIf = "triedLogin == true && approvedLogin == false">
                <span class="error">Invalid E-mail or Password</span>
            </div>
            
            <button type="submit" class="btn btn-primary" [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/");
    }
}

2 answers

  • answered 2022-01-13 05:21 aakash gupta

    Hi for double click you cannot use ngSubmit event binding on form.use dblclick event on button and capture that.

    <div class="central-form">
        <form class="login-form" [formGroup]="loginForm" autocomplete="disabled">
                <div class="form-group">
                    <label for="exampleInputEmail1">Email</label>
                    <input type="email" class="form-control" name="email" aria-describedby="emailHelp" placeholder="Enter email" formControlName="email" autocomplete="new-email">
                </div>
    
                <div class="form-group">
                    <label for="exampleInputPassword1">Password</label>
                    <input type="password" class="form-control" placeholder="Password" formControlName="password">
                </div>
                
                <div class="form-group" *ngIf = "triedLogin == true && approvedLogin == false">
                    <span class="error">Invalid E-mail or Password</span>
                </div>
                
                <button type="submit" (dblclick)="checkLogin()" class="btn btn-primary" [disabled]="!loginForm.valid">Submit</button>
        </form>
    </div>
    

  • answered 2022-01-13 08:17 gzn

    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);
     }
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum