Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

this.file é Undefined no Componente ao pressionar o botão de Upload/Submit

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>
1 resposta
solução!

Descobri o problema.

No método saveFile() que deve exibir o Preview, não estava funcionando, impedindo que o método upload() funcionasse.

Versão ainda com o erro (Com file no Singular: const [file] = pFile?.file;):

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);
    }

Versão corrigida (Com file no Plural: const [file] = pFile?.files;):

saveFile(pFile: any): void {
        console.log("NewAnimalComponent >> saveFile()");
        const [file]    = pFile?.files;
        this.file        =    file;

        const reader    =    new FileReader();
        reader.onload    =    (event: any) => {
            this.photoPreview    =    event.target.result;
        }
        reader.readAsDataURL(file);
    }