I have a Reactive Form and I want to upload an image and two color hex vaules and send the data tu DB. I'm using Angular Material and a Color picker plugin, but when I select the image or the color and trying to submit the form, the only logged info is the userId (from DataService), the other form fields are empty. On the contrary If I write something manually I have the fields with vaules. This is the .ts file:
customize.component.ts
import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { HttpClient, HttpEventType } from '@angular/common/http';
import { slideInOutAnimation } from '../animations';
import { CustomizeApiService } from './customize-api.service';
import { FormGroup, FormControl, FormGroupDirective, NgForm, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material';
import { Router } from '@angular/router';
import { DataService } from '../services/data.service';
import { ColorPickerService, Cmyk } from 'ngx-color-picker';
/** Error when invalid control is dirty, touched, or submitted. */
/** TODO copy error matcher in all components */
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}
@Component({
selector: 'app-customize',
templateUrl: './customize.component.html',
styleUrls: ['./customize.component.css'],
// make slide in/out animation available to this component
animations: [slideInOutAnimation],
// attach the slide in/out animation to the host (root) element of this component
// tslint:disable-next-line:use-host-property-decorator
host: { '[@slideInOutAnimation]': '' }
})
export class CustomizeComponent implements OnInit {
userId = '';
selectedFile: File = null;
imageFileName = '';
url = '../../assets/images/placeholder.png';
customizeForm: FormGroup;
matcher = new MyErrorStateMatcher();
SCZ_SU_ID: '';
SCZ_LOGO_URL: '';
SCZ_MAIN_COLOR: '';
SCZ_SECONDARY_COLOR: '';
public mainColor = '#ffffff';
public secondaryColor = '#ffffff';
constructor(
private data: DataService,
private router: Router,
private http: HttpClient,
private api: CustomizeApiService,
private formBuilder: FormBuilder,
public vcRef: ViewContainerRef,
private cpService: ColorPickerService
) { }
ngOnInit() {
this.data.getUserFromToken().subscribe(utente => {
this.userId = utente['SU_ID'];
console.log(this.userId);
this.setFormValues(utente['SU_ID']);
});
this.customizeForm = this.formBuilder.group({
'SCZ_SU_ID': [null],
'SCZ_LOGO_URL': [null],
'SCZ_MAIN_COLOR': [null],
'SCZ_SECONDARY_COLOR': [null]
});
}
onFileSelected(event) {
if (event.target.files && event.target.files[0]) {
this.selectedFile = event.target.files[0];
this.imageFileName = this.selectedFile.name;
// console.log(this.selectedFile.name);
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); // read file as data url
reader.onload = (_event) => { // called once readAsDataURL is completed
this.url = _event.target.result;
};
}
}
setFormValues(userId) {
this.customizeForm.setValue({
SCZ_SU_ID: userId,
SCZ_LOGO_URL: '',
SCZ_MAIN_COLOR: '',
SCZ_SECONDARY_COLOR: ''
});
}
onMainColorChange(mainColor: any): void {
this.mainColor = mainColor;
}
onSecondaryColorChange(secondaryColor: any): void {
this.secondaryColor = secondaryColor;
}
onFormSubmit(form: NgForm) {
console.log(form);
// this.api.postCustomization(form)
// .subscribe(res => {
// alert('file uploaded');
// this.router.navigate(['/sks']);
// }, (err) => {
// console.log(err);
// });
}
}
this is the html component file:
customize.component.html
<div class="container">
<mat-card>
<form [formGroup]="customizeForm" (ngSubmit)="onFormSubmit(customizeForm.value)">
<img mat-card-image height="200" width="200" [src]="url" alt="Photo Preview">
<div class="button-row">
<mat-form-field class="imageName">
<input matInput placeholder="Nome Immagine" formControlName="SCZ_LOGO_URL" [errorStateMatcher]="matcher" [value]="imageFileName"
(click)="imgFileInput.click()">
<mat-error>
<span *ngIf="!customizeForm.get('SCZ_LOGO_URL').valid && customizeForm.get('SCZ_LOGO_URL').touched">Scegli
un'immagine per il tuo logo</span>
</mat-error>
</mat-form-field>
<input hidden type="file" #imgFileInput (change)="onFileSelected($event)" />
</div>
<mat-form-field class="example-full-width">
<input matInput placeholder="Colore principale" [value]="mainColor" formControlName="SCZ_MAIN_COLOR" [errorStateMatcher]="matcher"
[style.background]="mainColor" [colorPicker]="mainColor" [cpPosition]="'right'" (colorPickerChange)="onMainColorChange($event)">
<mat-error>
<span *ngIf="!customizeForm.get('SCZ_MAIN_COLOR').valid && customizeForm.get('SCZ_MAIN_COLOR').touched">Scegli
il colore principale
</span>
</mat-error>
</mat-form-field>
<mat-form-field class="example-full-width">
<input matInput placeholder="Colore secondario" formControlName="SCZ_SECONDARY_COLOR" [errorStateMatcher]="matcher" [style.background]="secondaryColor"
[colorPicker]="secondaryColor" [cpPosition]="'right'" [value]="secondaryColor" (colorPickerChange)="onSecondaryColorChange($event)">
<mat-error>
<span *ngIf="!customizeForm.get('SCZ_SECONDARY_COLOR').valid && customizeForm.get('SCZ_SECONDARY_COLOR').touched">Scegli
il colore secondario</span>
</mat-error>
</mat-form-field>
<div class="button-row">
<a mat-stroked-button color="basic" [routerLink]="['/sks']" class="mat-stroked-button">
<mat-icon>keyboard_backspace</mat-icon>
</a>
<button type="submit" [disabled]="!customizeForm.valid" mat-raised-button color="primary">
<mat-icon>cloud_upload</mat-icon>
</button>
</div>
</form>
</mat-card>
</div>
for the complete project here I provide a StackBlitz: https://stackblitz.com/github/ufollettu/SEANSA
Could someone help me?