Angular#13 formGroup values are null (reactive forms) - html

Been trying to access form instance values bt they are all null..It worked fine in tempalate driven forms. I have imported ReactiveFormsModule. I have played around with the attr but I cant find what am missing??
The form is invalid the moment I use Validators.required meaning its empty
.component.html
<form [formGroup] ="tryForm" (ngSubmit)="onSubmit()" >
<div class="form-group">
<label>Name</label><br>
<input type="text" FormControlName ="name">
<span *ngIf="tryForm.invalid">Name required</span>
</div>
<!-- <div *ngIf="name.invalid" class="alert alert-danger"></div> -->
<div class="form-group">
<label>Email</label><br>
<input type="text" FormControlName ="email">
</div>
<div class="form-group">
<label>Message</label><br>
<input type="text" FormControlName ="message">
</div>
<button type = "submit" >Submit</button>
</form>
.component.ts
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormControl,FormGroup,Validators} from '#angular/forms';
import { Router} from '#angular/router'
#Component({
selector: 'app-log-in',
templateUrl: './log-in.component.html',
styleUrls: ['./log-in.component.css']
})
export class LogInComponent implements OnInit {
tryForm = this.fb.group({
name : [''],
email: [''],
message: [''],
});
constructor(private fb:FormBuilder,
private router: Router) { }
onSubmit(){
if (this.tryForm.status == "VALID"){
alert("Form Submitted Successfully.")
alert(this.tryForm.get("name")?.value);
this.tryForm.reset();

first you need to change the html FormControlName to formControlName. you can read the full explanation here.
HTML
<form [formGroup]="tryForm" (ngSubmit)="onSubmit(tryForm.value)">
<div class="form-group">
<label>Name</label><br />
<input type="text" formControlName="name" />
<span *ngIf="tryForm.invalid">Name required</span>
</div>
<div class="form-group">
<label>Email</label><br />
<input type="text" formControlName="email" />
</div>
<div class="form-group">
<label>Message</label><br />
<input type="text" formControlName="message" />
</div>
<button type="submit">Submit</button>
</form>
after that change your ts like bellow, make sure you initialize the form on ngOnInit.
TS
export class LogInComponent implements OnInit {
tryForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.createForm();
}
createForm() {
this.tryForm = this.fb.group({
name : [''],
email : [''],
message: [''],
});
}
onSubmit(data) {
console.log(data);
}
}
I replicate your code here

change this <input type="text" FormControlName ="email"> to this;
<input type="text" formControlName="email">
and build your form on ngOnInit,
ngOnInit(){
this.tryForm = this.fb.group({
name : [''],
email: [''],
message: [''],
});
}

Related

How can I get the value of this object?

I am using Angular 8 to get the data out of a radio input. When I send that data to Node then to Mongodb database, it is not register, and it appear like this in the db collection:
"__v" : 0
The output of the data that is being sent from Angular is: { type: administrator }, what I want to register in the db is only the word adminstrator. The Node console shows an error because of the object that is passed to the db when it expects a string value.
The Angular template is this:
<br>
<div class="w3-panel w3-border w3-margin" style="width: 500px; height: 550px">
<label class="w3-text-blue"><h2>New User</h2></label>
<label class="w3-text-blue"><b>Name and Last Name</b></label><br>
<input type="text" class="w3-input w3-border" [(ngModel)]="name" ><br>
<label class="w3-text-blue"><b>User</b></label><br>
<input type="text" class="w3-input w3-border" [(ngModel)]="user"><br>
<label class="w3-text-blue"><b>Password</b></label><br>
<input type="password" class="w3-input w3-border" [(ngModel)]="password"><br>
<label class="w3-text-blue"><b>Confirm Password</b></label><br>
<input type="password" class="w3-input w3-border" [(ngModel)]="confirm"><br>
<label class="w3-text-blue"><b>Type of User</b></label><br>
<form #myForm="ngForm" (submit)="sendRadio(myForm.value)" >
<input id="administrator" type="radio" name="type" class="w3-radio" value="administrator" ngModel>
<label for="administrador">Administrador</label> <br>
<input id="normal" type="radio" name="type" class="w3-radio" value="normal" ngModel>
<label for="normal">Moderador</label>
<br><br>
<button type="submit" (click)="createUser(user, password, name)" class="w3-button w3-round-xxlarge w3-green">Create</button>
<button class="w3-button w3-round-xxlarge w3-red">Clean Fields</button>
</form>
</div>
The component's typescript file:
import { Component, OnInit } from '#angular/core';
import { PersonService } from '../_services/person.service';
#Component({
selector: 'app-create-user',
templateUrl: './create-user.component.html',
styleUrls: ['./create-user.component.css']
})
export class CreateUserComponent implements OnInit {
user: any;
password: any;
confirm: any;
name: any;
type: string;
constructor(private ps: PersonService) { }
ngOnInit() {
}
sendRadio(value: any) {
this.type = value;
console.log(this.type); // <--- this outputs { type: administrator }
}
createUser(userU, userPassword, userName) {
if (this.password === this.confirm) {
if (this.password.length > 0 && this.confirm.length > 0) {
this.ps.createUser(userU, userPassword, userName, this.type);
} else {
console.log('Password has to match and be completed');
}
}else {
console.log('Password does not match');
}
}
}
The service to send the data (PersonService):
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class PersonService {
uri = 'http://localhost:3000';
constructor(private http: HttpClient) { }
createUser(userU, userPassword, userName, userType: string) {
const obj = {
user: userU,
password: userPassword,
name: userName,
type: userType
};
this.http.post(`${this.uri}/createUser`, obj)
.subscribe(res => console.log('User has been created'));
}
Just pass in
console.log(this.type.type);
because you need the value of the key for type. This prints out 'administrator' and you can pass that to your backend node.

Reactive form email validation in angular 7

I am new in angular.Email validation is not working in my reactive form validation. I have an error somewhere, but I'm not sure what it is.
Script:
this.loginForm = this.formBulder.group({
fname:['', Validators.required],
lname:['', Validators.required],
email:['', Validators.required],
password:['', Validators.required,Validators.maxLength(5)],
retypepassword:['', Validators.required,Validators.maxLength(5)]
});
https://stackblitz.com/edit/angular-forms-validation-tfzhug?file=app/app.component.html
try to this way
const emailPattern = '[a-zA-Z0-9.-_]{1,}#[a-zA-Z.-]{2,}[.]{1}[a-zA-Z]{2,63}';
mail = new FormControl('',Validators.compose( [Validators.required,Validators.pattern(emailPattern)]));
ts code
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormBuilder, Validators} from '#angular/forms';
import { UserService } from '../../shared/services/user.service';
const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
#Component({
selector: 'forget-password',
templateUrl: './forget-password.component.html',
styleUrls: ['./forget-password.component.css']
})
export class ForgetPasswordComponent implements OnInit {
form: FormGroup = new FormGroup({});
errors:any;
failed:boolean=false;
success:boolean=false;
constructor(private userService: UserService,private fb: FormBuilder) {
this.form = this.fb.group({
email: ['', [Validators.required, Validators.email, Validators.pattern(EMAIL_REGEX)]]
});
}
ngOnInit() {
}
get f() {
return this.form.controls;
}
isFieldValid(field: string) {
return (
(this.form.get(field).touched ||
this.form.get(field).untouched) && this.form.get(field).valid
);
}
forgetPassword() {
this.failed=false;
this.success=false;
this.userService.forgetPassword(this.form.value).subscribe(result=>{
this.success=true;
this.form.reset();
},errors=>{
this.failed=true;
this.errors=errors;
})
}
}
View
<form [formGroup]="form" (ngSubmit)="forgetPassword()">
<div class="md-form form-sm mb-2">
<i class="fa fa-envelope prefix"></i>
<input type="text" class="form-control" formControlName="email" type="email"
placeholder="Enter Your Email Address">
<div *ngIf="f.email.touched && f.email.invalid" class="text-danger">
<div *ngIf="f.email.errors.required">Email is required.</div>
<div *ngIf="f.email.errors.email">Email must be a valid email address</div>
</div>
</div>
<div class="text-center mt-2">
<button class="btn btn-primary" type="submit" [disabled]="!form.valid">Send Password Reset Email
<i class="fa fa-sign-in ml-1"></i>
</button>
</div>
<div *ngIf="failed" class="text-danger" role="alert">
<strong>Oops! </strong> <span *ngFor="let error of errors">{{error}}</span>
</div>
<div *ngIf="success" class="alert alert-success" role="alert">
Successfully change your password
</div>
</form>
you can try this :
this.loginForm = this.formBulder.group({
'fname': new FormControl('',Validators.required),
'lname': new FormControl('',Validators.required),
'email': new FormControl('',[Validators.required,Validators.email]),
'password': new FormControl('',[Validators.required,Validators.maxLength(5)]),
'retypepassword': new FormControl('',[Validators.required,Validators.maxLength(5)]),
});

Angular - Form validation without form tag

I'm trying to finalise a register form. I've to do it without using the form tag.
I've this registerform:
<div class="row">
<div class="center col-xs-8 col-xs-offset-2">
<p class="h5 text-center mb-4">{{ 'Signup' | translate }}</p>
<div class="form-group">
<label for="email">{{ 'SignupEmail' | translate }}</label>
<input type="text" [(ngModel)]="user.email" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }" />
<div *ngIf="submitted && f.email.errors" class="invalid-feedback">
<div *ngIf="f.email.errors.required">Email is required</div>
<div *ngIf="f.email.errors.email">Email must be a valid email address</div>
</div>
</div>
<div class="form-group">
<label for="username">{{ 'SignupUsername' | translate }}</label>
<input type="text" [(ngModel)]="user.name" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }" />
</div>
<div class="form-group">
<label for="password">{{ 'SignupPassword' | translate }}</label>
<input type="password" [(ngModel)]="user.password" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }" />
</div>
<div class="form-group">
<label for="birth">{{ 'SignupBirth' | translate }}</label>
<input type="date" [(ngModel)]="user.dateNaissance" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }" />
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-info" (click)="onSubmit()" >{{ 'SignupSubmit' | translate }}</button>
<img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
<div class="text-center">
{{ 'SignupAccount1' | translate }} <a routerLink="/login">{{ 'SignupAccount2' | translate }}</a>
</div>
</div>
</div>
</div>
The problem, is that the mail and the other input are always required even if i put a correct address mail in the input. And i don't get why...
Here is the register.component.ts
import {Component, OnInit} from '#angular/core';
import {FormGroup, FormBuilder, Validators} from '#angular/forms';
import {first} from 'rxjs/operators';
import {Router} from '#angular/router';
import {AlertService} from '../services/alert.service';
import {UserService} from '../services/user.service';
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.sass']
})
export class RegisterComponent implements OnInit {
registerForm: FormGroup;
loading = false;
submitted = false;
user: any;
constructor(private fb: FormBuilder, private router: Router, private userService: UserService, private alertService: AlertService) {
}
ngOnInit() {
this.registerForm = this.fb.group({
username: ['', Validators.required],
//gender: ['', Validators.required],
birth: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(8)]]
});
this.user = new Object();
}
click(ev) {
console.log(ev.target.defaultValue);
}
// convenience getter for easy access to form fields
get f() {return this.registerForm.controls;}
onSubmit() {
this.submitted = true;
// stop here if form is invalid
if (this.registerForm.invalid) {
window.alert("Informations invalides");
return;
}
this.loading = true;
this.userService.register(this.registerForm.value)
.pipe(first())
.subscribe(
data => {
this.alertService.success('Registration successful', true);
this.router.navigate(['/login']);
},
error => {
this.alertService.error(error);
this.loading = false;
});
}
}
Can you help me validate this form (but without adding the form tag)...
Thank you !
You had used reactive form, So use [formGroup] in div and inside that div use formControlName to achieve validation.
Here i have created one reactive form demo with validation and without form tag.
Stackblitz Demo without Form Tag

How to POST checkbox value instead of boolean value - Angular 5

I have this template-driven form:
<form #form="ngForm" (submit)="submitForm()" novalidate>
<div class="form-group" [class.has-error]="linkName.invalid">
<label class="control-label" for="name">Name</label>
<input #linkName="ngModel" type="text" class="form-control" name="name" id="name" [(ngModel)]="finalData.name" required />
<div *ngIf="linkName.invalid" class="alert alert-danger">Name is required</div>
</div>
<div class="form-group">
<label for="url">Url</label>
<input type="text" class="form-control" id="url" name="url" [(ngModel)]="finalData.url" readonly/>
</div>
<div class="checkbox" *ngFor="let tag of finalData.tags; index as i" [attr.data-index]="i">
<label><input type="checkbox" name="{{ 'checkbox' + tag }}" id="{{ 'checkbox' + tag }}" (ngModel)="finalData.tags[i]"/>{{ tag }}</label>
</div>
<button type="submit" [disabled]="form.invalid" class="btn btn-primary btn-success">Save</button>
</form>
I want to POST value from checkboxes based on whether they checked or not.
This way with one-way binding (ngModel) it will POST all tags whether they checked or not. If I use two-way binding [(ngModel)] it will POST boolean values and it will change name and id based on boolean value, which I don't want.
Example:
If i check this I want POST foo instead of true
<label><input type="checkbox" name="footag" id="footag" value="foo" [(ngModel)]="finalData.tags[i]"/>foo</label>
This is component used for data binding:
import { Component, OnInit, Injectable } from "#angular/core";
import { DataService } from "../shared/dataService";
import { FinalFormData } from "../shared/finalFormData";
import { ActivatedRoute, Router } from '#angular/router';
import { Observable } from "rxjs/Observable";
import { NgForm } from "#angular/forms";
#Component({
selector: "final-form",
templateUrl: "finalForm.component.html"
})
export class FinalFormComponent implements OnInit{
constructor(private data: DataService, private route: ActivatedRoute, private router: Router) {
}
public finalData: FinalFormData;
public errorMessage = "";
public isBusy = true;
submitForm() {
this.data.postData(this.finalData)
.subscribe(data => {
this.finalData = data;
this.router.navigate(["/"]);
}, err => console.log(err));
}
ngOnInit(): void {
//let url = encodeURIComponent(this.route.snapshot.queryParams['url']);
//this.data.loadData(url)
// .subscribe(finalData => {
// this.finalData = finalData;
// });
this.finalData = this.route.snapshot.data['finalData'];
}
}
FinalFormData class:
export class FinalFormData {
name: string;
url: string;
dateCreated: Date;
tags: any[];
}
you can use the ngModelChange method to pass the value and set it to any variable you want. Refer sample code snippet below:
<label><input type="checkbox" name="footag" id="footag" value="foo" [ngModel]="finalData.tags[i]" (ngModelChange)="CheckBoxValueChange('foo',finalData)"/>foo</label>
in the component.ts file, you can access the value and set it to any variable you want:
CheckBoxValueChange(checkboxValue:string,finalData:any){
finalData.checkboxText=checkboxValue;
alert(checkboxValue);
}

Angular 4 validation is showing when the page load's

i'm working on angular 4 form and set some validations on the input field but the validation is show when the page load's but i want the validation when the form is submitted or the email pattern is not valid.
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)"
[class.error]="!myForm.valid && myForm.touched">
<div class="field" [class.error]="!email.valid && email.touched">
<label for="email">Email</label>
<input type="email" id="email" name="email" [formControl]="email">
<div *ngIf="!email.valid"
class="ui error message">Email is invalid</div>
<div *ngIf="email.hasError('required')"
class="ui error message">Email is required</div>
</div>
<div *ngIf="!myForm.valid"
class="ui error message">Form is invalid</div>
<button type="submit">login</button>
</form>
Typescript code:
function EmailValidator(control: FormControl): { [s: string]: boolean } {
if (!control.value.match('^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$'))
{
return {invalidEmail: true};
}
}
#Component({
selector: 'app-login-form',
templateUrl: './login-form.component.html',
styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent implements OnInit {
myForm: FormGroup;
email: AbstractControl;
constructor(fb:FormBuilder) {
this.myForm = fb.group({
'Email': ['', Validators.compose([
Validators.required, EmailValidator])
]
});
this.email = this.myForm.controls['Email'];
}
onSubmit(form: string): void {
console.log('you submitted value:', form);
}
}
you can use
<div
*ngIf="myForm.get('email').hasErrors('required') &&
myForm.get('email').touched">
Email is required
</div>
And adapt hasError to your validation