javascriptangularangular-template-form

I am getting the following error: ERROR TypeError: Cannot read property 'invalid' of undefined


I have tried other solutions such as fixing form references but that didn't help me. Here is my form for a login

    <form [formGroup]="longinForm" (ngSubmit)="onSubmit()">
    <h1>Login Form</h1>

      <div class="form-group" >
        <label for="name" >Username</label>
        <input type="text" name ="user" [(ngModel)]="loginuserdata.user" 
 #user="ngModel" 
        class="form-control" required >
        <div *ngIf="submitted">
        <div [hidden]="user.valid || user.pristine" class="alert alert-danger">
          Username is required
        </div>
        </div>
      </div>

      <div class="form-group" >
        <label for="pass" >Password</label>
        <input type="text" name="pass" [(ngModel)]="loginuserdata.pass" #pass="ngModel"
        class="form-control"  required >
        <div *ngIf="submitted">
        <div [hidden]="pass.valid || pass.pristine" class="alert alert-danger">
            Password is required
        </div>
        </div>
      </div>
      <button type="submit" class="btn btn-success">Submit</button>
    </form>

also here is my login component

import { Component, OnInit, ViewChild } from '@angular/core';
import { NgForm, FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { LoginService } from './login.service';
import { ILoginData } from './login-data';

@Component({
  selector: 'app-loginform',
  templateUrl: './loginform.component.html',
  styleUrls: ['./loginform.component.css']
})
export class LoginformComponent implements OnInit {

  loginForm:FormGroup;
  loginuserdata : any[] = [];
  error:string;

  submitted=false;

  constructor(private route: Router,private service:LoginService) { }

  get f(){return this.loginForm.controls;}

  ngOnInit() {
    this.onSubmit();
  }

  onSubmit(){

    if(this.loginForm.invalid){return;}//form invalid stop here
    //form is valid do something
    this.submitted=true;
    if(this.f.user.value == "Admin" && this.f.pass.value == "Apassword"){
    this.service.getAdmin()
    .subscribe(data => this.loginuserdata = data)
              this.route.navigateByUrl('admin');
              err => this.error = err;
              console.log(this.error);
    }

  }

}

If you guys need to see any other pieces of my code let me know please help me out I tried something similar to an answer solved to this but it didn't work for me.


Solution

  • You need to build the form controls, you have it defined but you need something like the following. You need to initialise the form group.

    import { NgForm, FormGroup, FormBuilder } from '@angular/forms'; 
    
    //Be sure to import formBuilder and inject through constructor. This will allow you 
    //to manage how you will build the form and add validation.
    //Its a helper class provided by Angular to help us explicitly declare forms.
    
    constructor( private formBuilder: FormBuilder ){}
    
    public ngOnInit(): void {
        this.loginForm = this.formBuilder.group({
        username: ['', Validators.required],
        password: ['', Validators.required]
    });
    

    This is where you can define the controls and the validators for the form group. (This example would just dictate that there needs to be a value for each in order to be valid. This should be built in the ngOnInit.

    Then in your template you can remove the [(ngModel)] and make it look like the following. The value for the input will then be held within the control when you need to access it.

    <form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
      <input type="text" name ="user" [formControlName]="'username'" 
      class="form-control" required>
    <form>
    

    Above would serve as an example for the login username / email. Also as mentioned in the comments you have a typo in the form in the HTML.

    This should then be valid when you are trying to access the valid and invalid properties of the from group. Comment if you have any trouble.

    Here is the Angular documentation for reactive forms.