Home > Enterprise >  How to make angular submit fire only once?
How to make angular submit fire only once?

Time:01-13

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>
  •  Tags:  
  • Related