Home > Net >  Angular 14 FormGroup Argument of type 'Partial ...are incompatible
Angular 14 FormGroup Argument of type 'Partial ...are incompatible

Time:11-04

I'm trying to make a login form using Angular 14 but i have this error message : Argument of type 'Partial<{ email: ((control: AbstractControl<any, any>) => ValidationErrors | null)[] | null; password: ValidatorFn[] | null; }>' is not assignable to parameter of type '{ email: String; password: String; }'. Types of property 'email' are incompatible. Type '((control: AbstractControl<any, any>) => ValidationErrors | null)[] | null | undefined' is not assignable to type 'String'. Type 'undefined' is not assignable to type 'String'.

After some searching i can understand that's because we can disable a formControl, and that will make this control not in the value. But after some tries, i don't get it to update my code and continue without this error .

login.component.ts

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from 
'@angular/forms';
import { Router } from '@angular/router';
import { AccountService } from 
 'src/app/services/account.service';
import { AuthService } from 
'src/app/services/auth.service';
import { TokenService } from 
'src/app/services/token.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
 })
export class LoginComponent implements OnInit {

loginForm = new FormGroup({
email: new FormControl([Validators.required, 
Validators.email],),
password: new FormControl([ Validators.required, 
Validators.minLength(6), Validators.maxLength(6)])

})

constructor(private authService: AuthService,
        private tokenService: TokenService,
        private router: Router,
        private accountService: AccountService
         ) { }

ngOnInit(): void {
}

login() {





 this.authService.login(this.loginForm.value).subscribe((res: any) => {
  this.handleResponse(res)
 })
 }

handleResponse(res: Object){
this.tokenService.handle(res)
this.accountService.changestatus(true)
this.router.navigateByUrl("/posts")
}

 }

my auth.service.js

import { Injectable } from '@angular/core';
import { LoginComponent } from '../components/login/login.component';
import { HttpClient} from "@angular/common/http"
import { LocalizedString } from '@angular/compiler';

@Injectable({
 providedIn: 'root'
})
export class AuthService {

  authUser: any = {
  token: null,
  user: {
  id: null,
  name: null,
  email: null
 }
  };
  constructor(
  private http: HttpClient
 ) {}

  login(data: { email: String, password: String }){
  return this.http.post("http://localhost:3000/api/register", data);
 }

sign(data: { name : String, email: String, password: String, age: Number, nourriture: 
 String }){
  return this.http.post("http://localhost:3000/api/login", data);
}


}

CodePudding user response:

Typescript issues

Do not use the constructor as a type.

So, for example,

login(data: { email: String, password: String }){}

should be

login(data: { email: string, password: string }){}

Using interfaces will make your code look a lot cleaner.

FormControl

The FormControl constructor is overloaded. I suggest using the following signature,


loginForm = new FormGroup({
    email: new FormControl("", 
        {
            nonNullable: true,
            validators: [
                Validators.required, 
                Validators.email
            ]
        }
    ),
    password: new FormControl("",
        {
            nonNullable: true,
            validators: [
                Validators.required,
                Validators.minLength(6),
                Validators.maxLength(6)
            ]
        }
    );

Note I never remember what the signatures are. I let VS Code help me in this by looking at the types that pop up when I hover over FormControl. For reference the constructor signatures are here (click show more) https://angular.io/api/forms/FormControl#constructor

In addition I recommend typing your forms. This will make your IDE work for you. See https://angular.io/guide/typed-forms#optional-controls-and-dynamic-groups

Partial type

If you know none of the form controls will ever be disabled you can use loginForm.getRawValue(). This gets all values regardless of disabled status.

  • Related