How to set model data in Reactive Forms, Angular 9 - html

I started to study angular, i created a single crud using Angular 9 and Spring boot, but i have a question, what I'm trying to do is to get the data of the table below and move it for a reactive form to upload the data.
How to solve the issue?
enter image description here
.
enter image description here
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group">
<label for="">Nome</label>
<input type="text" formControlName="nome" class="form-control">
</div>
<div class="form-group">
<label for="">email</label>
<input type="text" formControlName="email" class="form-control">
</div>
<div class="form-group">
<label for="">username</label>
<input type="text" formControlName="username" class="form-control">
</div>
<button class="btn btn-outline-primary"> Salvar</button>
<button [routerLink]="['/']" style="margin-left: 1%;" class="btn btn-outline-warning"> Voltar</button>
</form>
My app-routing.module.ts:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ShowContactComponent } from './Componets/contact/show-contact/show-contact.component'
import { CreateContactComponent } from './Componets/contact/create-contact/create-contact.component'
const routes: Routes = [
{path:'', component:ShowContactComponent},
{path:'create', component:CreateContactComponent},
{path:'create/:id', component:CreateContactComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { Contact } from '../contact-model/Contact';
import { ContactService } from '../../contact.service';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-create-contact',
templateUrl: './create-contact.component.html',
styleUrls: ['./create-contact.component.css']
})
export class CreateContactComponent implements OnInit {
form:FormGroup;
contacts:Contact[] = []
contact:Contact
constructor(private service:ContactService, private router:Router, private fb:FormBuilder, private AR:ActivatedRoute) { }
ngOnInit() {
// this.paramService();
this.validateForms();
}
submit(){
const formValue = this.form.value;
const contact:Contact = new Contact(formValue.nome, formValue.email ,formValue.username );
this.service.create(contact).subscribe(response =>{
this.contacts.push(response);
this.router.navigate([''])
console.log(response);
})
}
paramService(){
const formValue = this.form.value;
const contact:Contact = new Contact(formValue.nome, formValue.email ,formValue.username );
console.log(contact);
this.service.readOne(this.contact.id).subscribe(response =>{
this.form.patchValue({
nome: contact.nome,
email: contact.email,
username: contact.username
});
});
}
validateForms(){
this.form = this.fb.group({
nome: ['', Validators.required],
email: ['', Validators.required],
username: ['', Validators.required]
})
}
}

You can do it in this way:
validateForms(data?: Contact){
this.form = this.fb.group({
nome: [data.name || '', Validators.required],
email: [data.email || '', Validators.required],
username: [data.username || '', Validators.required]
})
}
Now you should pass the data to show in your form:
ngOnInit() {
// const contact: Contact = ...
this.validateForms(contact);
}
Please change 'validateForms' name to 'initForm'.

Related

How to put Variable in Statement [Angular, TypeScript]

This is in Angular,
I want to use variable to change my conditional statement so I don't need to modify every variable and type again
This is a code in input tag HTML
.
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
.
public form: FormGroup;
private formBuilder: FormBuilder
.
get f() { return this.form.controls; }
.
this.form = this.formBuilder.group({
id: ['00000000-0000-0000-0000-000000000000'],
name: ['', Validators.required],
email: ['', [Validators.required, Validators.pattern("^[a-z0-9._%+-]+#[a-z0-9.-]+\\.[a-z]{2,4}$")]],
oraganize: ['', Validators.required],
});
.
<input
...
[ngClass]="{'is-invalid': f.name.invalid && (f.name.dirty || f.name.touched)}"
>
So my code will change every time when there is a new input such as name, email, oraganize, etc
I want to build a function that I can pass some string and make it super nice not to modify all the time with the long line.
ex:
public checkCondition(attribute: string): boolean{
return (`this.f.${attribute}.invalid && (this.f.${attribute}.dirty || this.f.${attribute}.touched)`);
}
so I can use as...
<input
...
[ngClass]="{'is-invalid': checkCondition("name")}"
>
Please, So can I do it this way or not? or does it just works with only the string, not the condition?
it looks like you where very close. this should work.
public checkCondition(key: string): boolean{
return this.f[key].invalid && (this.f[key].dirty || this.f[key].touched);
}
or you can further simplify it
public checkCondition(key: string): boolean{
return {
'is-invalid': this.f[key].invalid && (this.f[key].dirty || this.f[key].touched)
};
}
and you html
<input [ngClass]="checkCondition('name')" />
Here is what it would look like all together
import { Component } from '#angular/core';
import { FormBuilder, Validators } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
form = this.formBuilder.group({
id: ['00000000-0000-0000-0000-000000000000'],
name: ['', Validators.required],
email: ['', [Validators.required, Validators.pattern("^[a-z0-9._%+-]+#[a-z0-9.-]+\\.[a-z]{2,4}$")]],
oraganize: ['', Validators.required],
});
constructor(private formBuilder: FormBuilder) {}
checkCondition(key: string) {
const control = this.form.get(key);
if (!control) {
return;
}
return {
'is-invalid': control.invalid && (control.dirty || control.touched)
};
}
}
<form [formGroup]="form">
<input formControlName="id" [ngClass]="checkCondition('id')" />
<input formControlName="name" [ngClass]="checkCondition('name')" />
<input formControlName="email" [ngClass]="checkCondition('email')" />
<input formControlName="oraganize" [ngClass]="checkCondition('oraganize')" />
</form>
Here is a working stackBlitz
https://stackblitz.com/edit/angular-ivy-cvwmis?file=src%2Fapp%2Fapp.component.html

Angular 11 Forms and Http POST

I'm trying to post information I entered from my text boxes but I'm receiving an error,
core.js:6210 ERROR TypeError: Cannot read property 'toString' of undefined
I was wondering as to why my variables are appearing as undefined? Additionally, how might I fix this problem?
Component File
import { Component, Inject, OnInit } from '#angular/core';
import { HttpClient, HttpParams } from '#angular/common/http';
import { FormGroup, FormControl, FormBuilder } from '#angular/forms';
#Component({
selector: 'app-WeatherData',
templateUrl: './AddWeatherData.component.html',
})
export class PostDataComponent {
baseUrl: string;
date: number;
temperatureC: number;
summary: string;
weatherForm: FormGroup;
constructor(public http: HttpClient, #Inject('BASE_URL') baseUrl: string, private formBuilder: FormBuilder) {
this.baseUrl = "https://localhost:44347/WeatherForecast";
this.weatherForm = formBuilder.group({
Date: new FormControl(),
TemperatureC: new FormControl(),
Summary: new FormControl()
});
}
CreateData() {
const params = new HttpParams({
fromObject: {
'date': this.weatherForm.value.date.toString(),
'temperatureC': this.weatherForm.value.temperatureC.toString(),
'summary': this.weatherForm.value.summary.toString()
}
});
let endPoints = '';
console.log(params);
this.http.post(this.baseUrl + endPoints, {},{ params: params }).subscribe(data => {
console.log(data);
});
}
}
My HTML file includes the forms setup and the type declarations are text for each of the variables I included. Is this an issue?
HTML File
<form [formGroup]="weatherForm">
<div class="form-group">
<label for="inputDate">Date</label>
<input type="text" class="form-control" id="inputDate" formControlName="Date">
</div>
<div class="form-group">
<label for="inputTemp">Temperature C</label>
<input type="text" class="form-control" id="inputTemp" formControlName="TemperatureC">
</div>
<div class="form-group">
<label for="inputSummary">Summary</label>
<input type="text" class="form-control" id="inputSummary" formControlName="Summary">
</div>
<button type="submit" class="btn btn-primary" (click)="CreateData()">Add New Weather Data</button>
</form>
debug at
fromObject: {
'date': this.weatherForm.value.date.toString(),
'temperatureC': this.weatherForm.value.temperatureC.toString(),
'summary': this.weatherForm.value.summary.toString()
}
and check the value of this.weatherForm.value
all properties are case sensitive TemperatureC is not equal to temperatureC
and if you execute undefine.toString() then you will get the error
Please replace your code with below,
import { Component, Inject, OnInit } from '#angular/core';
import { HttpClient, HttpParams } from '#angular/common/http';
import { FormGroup, FormControl, FormBuilder } from '#angular/forms';
#Component({
selector: 'app-WeatherData',
templateUrl: './AddWeatherData.component.html',
})
export class PostDataComponent {
baseUrl: string;
date: number;
temperatureC: number;
summary: string;
weatherForm: FormGroup;
constructor(public http: HttpClient, #Inject('BASE_URL') baseUrl: string, private formBuilder: FormBuilder) {
this.baseUrl = "https://localhost:44347/WeatherForecast";
this.weatherForm = formBuilder.group({
Date: new FormControl(),
TemperatureC: new FormControl(),
Summary: new FormControl()
});
}
CreateData() {
const params = new HttpParams({
fromObject: {
'date': this.weatherForm.value.Date.toString(),
'temperatureC': this.weatherForm.value.TemperatureC.toString(),
'summary': this.weatherForm.value.Summary.toString()
}
});
let endPoints = '';
console.log(params);
this.http.post(this.baseUrl + endPoints, {},{ params: params }).subscribe(data => {
console.log(data);
});
}
}

Angular TypeError: Cannot read property '0' of undefined when using event.target.file[0]

I'm currently trying to take a file input from a user and store it to Firebase Storage using AngularFire. Since it's undefined, I'm convinced that whatever file they're looking at, it's NULL, but my UI clearly shows that I'm successfully inputting a file, but the error gets caught as soon as I select the file. Am I misunderstanding how the input sends information to my TypeScript file?
Here's my TS file:
import { AngularFirestore } from '#angular/fire/firestore';
import { Component, OnInit, Input, ChangeDetectorRef } from '#angular/core';
import { finalize, tap, map } from 'rxjs/operators';
import { FormBuilder, FormGroup, FormArray, Validators } from '#angular/forms';
import { SubmitPostService } from './submit-post.service';
import { Post } from '../post.model';
import { Observable } from 'rxjs';
#Component({
selector: 'app-post-creation',
templateUrl: './post-creation.component.html',
styleUrls: ['./post-creation.component.scss']
})
export class PostCreationComponent implements OnInit {
private uuidv4 = require('uuid/v4');
// Main task
task: AngularFireUploadTask;
// Progress Monitoring
percentage: Observable<number>;
// Download URL
downloadURL: Observable<string>;
myForm: FormGroup;
post: Post;
ref: AngularFireStorageReference;
files: Observable<any>;
constructor(
private formBuilder: FormBuilder,
private postService: SubmitPostService,
private storage: AngularFireStorage,
) { }
ngOnInit() {
this.myForm = this.formBuilder.group({
title: ['', [Validators.required]],
artists: ['', [Validators.required]],
description: '',
medium: ''
});
this.myForm.valueChanges.subscribe(console.log);
}
onSubmit() {
this.post = new Post(
this.uuidv4(),
this.myForm.get('artists').value,
this.myForm.get('title').value,
new Date(),
new Date(),
`images/${Date.now()}_${this.myForm.get('title').value}`,
this.myForm.get('description').value,
this.myForm.get('medium').value
);
this.postService.submitPost(this.post);
}
upload(event: any) {
console.log('Upload successful');
try {
const file = event.target.file[0];
// The storage path
const path = `images/${Date.now()}_${file.name}`;
// Reference to storage bucket
this.ref = this.storage.ref(path);
// Main Task
this.task = this.ref.put(file);
// Tracks progress
this.percentage = this.task.percentageChanges();
this.percentage = this.task.snapshotChanges()
.pipe(map(s => (s.bytesTransferred / s.totalBytes) * 100));
this.downloadURL = this.ref.getDownloadURL();
} catch (err) { console.log(err); }
}
}
Here's my HTML:
<div>
<div class="progress">
<progress max="100" [value]="(percentage | async)"></progress>
</div>
<h1>Post Creation</h1>
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput placeholder="Title" formControlName="title">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Artists" formControlName="artists">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Description" formControlName="description">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Medium" formControlName="medium">
</mat-form-field>
<br>
<input type="file" (change)="upload($event)" accept=".png,.jpg">
<br>
<br>
<button mat-raised-button [disabled]="myForm.invalid" color="primary">Submit Post</button>
</form>
</div>
</body>
I've successfully created the Post objects in the Firestore, so it's not an issue of my firebase configs aren't correctly initialize.
In your upload method, in the const file = event.target.file[0]; statement, the file property should be plural

How to show error message for typing in text box any thing else except number / numeric in angular 8

I have a text box,which only allows to type number,If I try to type alphabet or any special character it should show error below the text box.Once I start typing numeric error should hide.Here I am using reactive form of angular 8. Here is the code below
home.component.html
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div class="form-row">
<div class="form-group col">
<label>Title</label>
<input type="number" formControlName="title" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.title.errors }"/>
<div *ngIf="submitted && f.title.errors" class="invalid-feedback">
<div *ngIf="f.title.errors.required">Title is required</div>
</div>
</div>
</div>
<div class="text-center">
<button class="btn btn-primary mr-1">Register</button>
<button class="btn btn-secondary" type="reset" >Cancel</button>
</div>
</form>
home.component.ts
import { Component, OnInit } from '#angular/core';
import { CommonserviceService } from './../utilities/services/commonservice.service';
import { FormBuilder, FormControl, FormGroup, Validators } from '#angular/forms';
import {NgbModal, ModalDismissReasons} from '#ng-bootstrap/ng-bootstrap';
declare var $: any;
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
imageSource :any;
statusdata: any;
closeResult: string;
registerForm: FormGroup;
submitted = false;
constructor(private modalService: NgbModal,private formBuilder: FormBuilder) {}
ngOnInit() {
this.statusdata = [
{ id: 1, name: "cat"},
{ id: 2, name: "arctichare"},
{ id: 3, name: "baboon" },
];
this.registerForm = this.formBuilder.group({
title: ['', Validators.required]
});
}
get f() { return this.registerForm.controls; }
onSubmit() {
this.submitted = true;
// stop here if form is invalid
if (this.registerForm.invalid) {
return;
}
// display form values on success
alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.registerForm.value, null, 4));
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UsermanagementComponent } from './usermanagement/usermanagement.component';
import { HomeComponent } from './home/home.component';
import { HeaderComponent } from './shared/header/header.component';
import { LoginComponent } from './login/login.component';
import {HttpModule} from '#angular/http';
import { FormsModule,ReactiveFormsModule } from '#angular/forms';
import {NgbModule} from '#ng-bootstrap/ng-bootstrap';
#NgModule({
declarations: [
AppComponent,
UsermanagementComponent,
HomeComponent,
HeaderComponent,
LoginComponent
],
imports: [
NgbModule,
BrowserModule,
AppRoutingModule,
HttpModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
I think you can catch input values with keydown or keyup.
change your input as following:
<input type="number" formControlName="title" class="form-control"
#inp (keydown)="checkValue($event, inp.value)"
[ngClass]="{ 'is-invalid': submitted && f.title.errors }"/>
And add following method to your component:
checkValue(event: KeyboardEvent, val: any) {
const allowedChars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, "Backspace", "ArrowLeft", "ArrowRight"];
let isValid: boolean = false;
for (let i = 0; i < allowedChars.length; i++) {
if (allowedChars[i] == event.key) {
isValid = true;
break;
}
}
if (!isValid) {
event.preventDefault();
alert('Enter only number'); // or do smt about your error message
}else{
//reset error status here
}
}

how to specify the value of our checkbox

I want that when the user checks on checkbox, the value be "l.code" instead of a Boolean value
Here's my code
<div class="form-group">
<label>Critères : </label>
<div class="checkbox-inline" *ngFor="let l of lesCriteres; let i= index">
<label>
<input type="checkbox" [value]="l.code" [(ngModel)]="actif.lesCriteresActifs[i].critere.code">{{l.code}}
</label>
</div>
</div>
But it does not work ! when I check, it gives me "true" instead of "l.code". Thanks !
You can use "change" event handler with event binding on checkbox.
In html
<form>
<div *ngFor="let l of lesCriteres">
<input type="checkbox" value="l.code" (change)="onChangeEvent($event, l.code)"> {{l.code}}<br>
</div>
</form>
In ts
onChangeEvent(eventValue, valueOfCheckbox){
alert(valueOfCheckbox);
}
You can do something like below :
HTML:
<div *ngFor="let data of emails">
<input type="checkbox" [value]="data.email" (change)="onChange(data.email, $event.target.checked)"> {{data.email}}<br>
</div>
ts:
import { Component } from '#angular/core';
import { FormGroup, FormBuilder, FormArray, FormControl } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular 6';
emailFormArray = [];
emails = [{ email: "email1" }, { email: "email2" }, { email: "email3" }, { email: 'email4' }]
myForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.myForm = this.fb.group({
useremail: this.fb.array([])
});
}
onChange(email: string, isChecked: boolean) {
if (isChecked) {
this.emailFormArray.push(email);
} else {
let index = this.emailFormArray.findIndex(x =>{
console.log(x);
return x == email
});
console.log(index)
this.emailFormArray.splice(index,1);
}
console.log(this.emailFormArray)
}
}
STACKBLITZ