简体   繁体   中英

Login Form fails to push value to function onSubmit

I'm trying to make a login form in Angular, but I'm getting lots of errors, username does get passed into the onSubmit() function, but this.loginForm.value stays empty. I tried using promises without any avail.

My component ts file:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { first } from 'rxjs/operators';

import { AuthenticationService} from '../services/authentication.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  returnUrl: string;
  loginForm: FormGroup;
  submitted = false;
  error = '';
  loading = false;

  constructor(private router: Router,
              private route: ActivatedRoute,
              private formBuilder: FormBuilder,
              private authenticationService: AuthenticationService) {
      /* // redirect to home if already logged in
      if (this.authenticationService.currentUserValue) {
        this.router.navigate(['/avior/dashboard']);
    } */
  }

  ngOnInit() {
    this.loginForm = this.formBuilder.group({
      username: ['', Validators.required, Validators.minLength(2)],
      password: ['', Validators.required, Validators.minLength(6)]
  });
   // get return url from route parameters or default to '/login'
    this.returnUrl = this.route.snapshot.queryParams.returnUrl || '/login';
  }

  // convenience getter for easy access to form fields
get f() { return this.loginForm.controls; }

  login(userName: string, password: string) {

    this.router.navigateByUrl('/dashboard');

  }

  onSubmit(username, password) {
    this.submitted = true;
    console.log(username); // this prints out the correct username!
    console.log('OnSubmit is executed');
    console.log(this.loginForm.value); // THIS IS SOMEHOW EMPTY WTF
    // stop here if form is invalid
    if (this.loginForm.invalid) {
        return console.log('LoginForm Invalid');
    }
    this.loading = true;
    this.authenticationService.login(this.f.username.value, this.f.password.value)
        .pipe(first())
        .subscribe(
            data => {
                this.router.navigate([this.returnUrl]);
            },
            error => {
                this.error = error;
                this.loading = false;
            });
}
}

My component HTML file:

<div class="container">
<div class="row">
  <div class="col-sm-9 col-md-7 col-lg-5 mx-auto">
    <div class="card card-signin my-5">
      <div class="card-body">
        <h5 class="card-title text-center">Login</h5>
        <br>
        <form [formGroup]="loginForm" class="form-signin" (ngSubmit)="onSubmit(this.f['username'].value, this.f['password'].value)">
          <div class="form-label-group">
            <input #userName formControlName="username" type="text" id="inputUser" class="form-control" placeholder="Username" required autofocus [ngClass]="{ 'is-invalid': submitted && f.username.errors }">
            <label for="inputUser">Benutzername</label>
            <div *ngIf="submitted && f['username'].errors" class="invalid-feedback">
                <div *ngIf="f['username'].errors.required">Benutzername ist erforderlich</div>
            </div>
          </div>

          <div class="form-label-group">
            <input #password type="password" formControlName="password" id="inputPassword" class="form-control" placeholder="Password" required [ngClass]="{ 'is-invalid': submitted && f.password.errors }">
            <label for="inputPassword">Passwort</label>
            <div *ngIf="submitted && f['password'].errors" class="invalid-feedback">
                <div *ngIf="f['password'].errors.required">Password is required</div>
            </div>
          </div>
          <br>
          <button class="btn btn-dark btn-block" type="submit">login</button>
        </form>
      </div>
    </div>
  </div>
</div>

My errors:

Error1 (unknown from where):

ERROR Error: "[object Object]"
    Angular 8
        resolvePromise
        resolvePromise
        scheduleResolveOrReject
        invokeTask
        onInvokeTask
        invokeTask
        runTask
        drainMicroTaskQueue
core.js:15724
    Angular 4
        defaultErrorLogger
        handleError
        next
        schedulerFn
    RxJS 5
        __tryOrUnsub
        next
        _next
        next
        next
    Angular 11
        emit
        onHandleError
        invoke
        run
        runOutsideAngular
        onHandleError
        handleError
        runGuarded
        _loop_1
        microtaskDrainDone
        drainMicroTaskQueue

Errors that appeared AFTER I added formControlNames to the HTML:

ERROR Error: "Expected validator to return Promise or Observable."
    Angular 8
        toObservable
        composeAsync
        _runAsyncValidator
        updateValueAndValidity
        setValue
        updateControl
        setUpViewChangePipeline
        _handleInput
    View_LoginComponent_0 LoginComponent.html:12
    Angular 13
        handleEvent
        callWithDebugContext
        debugHandleEvent
        dispatchEvent
        renderEventHandlerClosure
        decoratePreventDefault
        invokeTask
        onInvokeTask
        invokeTask
        runTask
        invokeTask
        invokeTask
        globalZoneAwareCallback

Also a couple of these:

ERROR CONTEXT 
Angular 8
core.js:15724
    Angular 4
        defaultErrorLogger
        handleError
        next
        schedulerFn
    RxJS 5
        __tryOrUnsub
        next
        _next
        next
        next
    Angular 11
        emit
        onHandleError
        invoke
        run
        runOutsideAngular
        onHandleError
        handleError
        runGuarded
        _loop_1
        microtaskDrainDone
        drainMicroTaskQueue

Stackblitz: https://stackblitz.com/edit/angular-z6nrkg (seems to fail)


Update :

The object object error was Firefox specific, Chrome gives me this error:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[AviorBackendService -> HttpClient]: 
  StaticInjectorError(Platform: core)[AviorBackendService -> HttpClient]: 
    NullInjectorError: No provider for HttpClient!
Error: StaticInjectorError(AppModule)[AviorBackendService -> HttpClient]: 
  StaticInjectorError(Platform: core)[AviorBackendService -> HttpClient]: 
    NullInjectorError: No provider for HttpClient!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:8896)
    at resolveToken (core.js:9141)
    at tryResolveToken (core.js:9085)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8982)
    at resolveToken (core.js:9141)
    at tryResolveToken (core.js:9085)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8982)
    at resolveNgModuleDep (core.js:21218)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:21907)
    at injectInjectorOnly (core.js:1774)
    at resolvePromise (zone.js:831)
    at resolvePromise (zone.js:788)
    at zone.js:892
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at drainMicroTaskQueue (zone.js:601)

You are missing brackets around your validators, should be:

  username: ["", [Validators.required, Validators.minLength(2)]],
  password: ["", [Validators.required, Validators.minLength(6)]]

Seems to work fine after that. Also I would change your error checkings a bit, in my opinion is more intuitive to do:

  <div *ngIf="loginForm.hasError('required', 'username')">...</div>
  <div *ngIf="loginForm.hasError('minlength', 'username')">...</div>

Also in submit I would pass the value of the form, instead of the username and password separately. You get a nice object from the form values:

(ngSubmit)="onSubmit(loginForm.value)"

STACKBLITZ

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM