Estava recebendo erros 500 ao postar um Novo Animal na API.
Depois de muito quebrar a cabeça, descobri que no Componente de Novo Animal, o atributo "file" está Undefined.
Não estou conseguindo entender onde posso estar errando. Alguém tem ideia de como descobrir a quebra entre o Template e o Componente?
Componente:
import { HttpEvent, HttpEventType } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { finalize } from 'rxjs';
import { AnimalsService } from '../animals.service';
@Component({
selector: 'app-new-animal',
templateUrl: './new-animal.component.html',
styleUrls: ['./new-animal.component.css'],
})
export class NewAnimalComponent implements OnInit {
animalForm!: FormGroup;
file!: File;
photoPreview!: string;
completedPercent: number = 0;
constructor(
private animalsService: AnimalsService,
private formBuilder: FormBuilder,
private router: Router
) {
console.log("NewAnimalComponent >> Constructor()");
}
ngOnInit(): void {
console.log("NewAnimalComponent >> ngOnInit()");
this.animalForm = this.formBuilder.group({
file: ['', Validators.required],
description: ['', Validators.maxLength(300)],
allowComments: [true]
});
}
uploadPhoto() {
console.log("NewAnimalComponent >> uploadPhoto()");
const allowComments = this.animalForm.get('allowComments')?.value ?? false;
const description = this.animalForm.get('description') ?.value ?? '';
// É aqui que eu descobri o Undefined
console.log(`NewAnimalComponent >> uploadPhoto() >> this.file = ${this.file}`);
this.animalsService
.uploadPhoto(description, allowComments, this.file)
.pipe(
finalize(
() => {
return this.router.navigate(['animals'])
}
)
)
.subscribe(
{
next:
(event:HttpEvent<any>) => {
if ( event.type === HttpEventType.UploadProgress ) {
const total = event.total ?? 1;
this.completedPercent = Math.round(100 * (event.loaded / total));
}
},
error:
(error) => {
console.log(error);
}
}
);
}
saveFile(pFile: any): void {
console.log("NewAnimalComponent >> saveFile()");
const [file] = pFile?.file;
this.file = file;
const reader = new FileReader();
reader.onload = (event: any) => {
this.photoPreview = event.target.result;
}
reader.readAsDataURL(file);
}
}
Template:
<p>new-animal works!</p>
<div class="container">
<form [formGroup]="animalForm"
class="row"
(submit)="uploadPhoto()">
<div class="col-md-6 text-center">
<div class="form-group"
*ngIf="!photoPreview; else previewTemplate">
<button type="button"
class="btn btn-primary"
(click)="fileInput.click()">
<i class="fa fa-image fa-4x align-middle"></i>
</button>
<input type="file"
#fileInput
hidden
formControlName="file"
accept="image/*"
(change)="saveFile($event.target)">
<app-messages message="Por favor, selecione uma foto"
*ngIf="!!animalForm.get('file')?.errors?.['required']"></app-messages>
</div>
<ng-template #previewTemplate>
<app-animal-thumbnail [url]="photoPreview"
title="Preview"></app-animal-thumbnail>
</ng-template>
</div>
<div class="col-md-6">
<div class="form-group">
<textarea formControlName="description"
class="form-control form-control-sm"
placeholder="Descrição do Animal"
></textarea>
<app-messages message="O tamanho máximo é de 300 caracteres"
*ngIf="!!animalForm.get('description')?.errors?.['maxLength']"></app-messages>
</div>
<div class="form-group">
<label class="text-muted">
Permitir Comentários
<input type="checkbox"
formControlName="allowComments">
</label>
</div>
<div *ngIf="!completedPercent; else divUpload">
<button type="submit"
class="btn btn-primary btn-block"
[disabled]="animalForm.invalid">
Upload
</button>
<a routerLink="['animals']"
class="btn btn-secondary btn-block ">
Cancelar
</a>
</div>
<ng-template #divUpload>
<div class="text-center display-4">
Percentual do Upload {{completedPercent}} %
</div>
</ng-template>
</div>
</form>
</div>