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
String
,Number
are the JavaScript constructors. E.g.const x = new Number(“5”)
. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Numberstring
,number
are the typescript types for string and number.
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.