1
resposta

Problem no preview do projeto lista animais angular

Olá. Fiz o curso "Angular: controle e fluxo de navegação" e ao final do projeto, duas coisas não funcionaram.

1° o preview que mostar a imagem do gato não aprece quando a imagem é carregada e o percentual de carregamento também não. A imagem é carregada e vai para lista normalmente.

2° No botão de cancelar, ele deveria voltar para a tela de lista de animais, mas não vai. Utilizei o routerLink="['animais']", mas não deu certo.

Abaixo seguem os códigos do template e do componente. Se alguém puder dar uma ajuda fico grato.

 <div class="container">
  <form [formGroup]="formularioAnimal" class="row" (submit)="upload()">
      <div class="col-md-6 text-center" >
        <div class="form-group" *ngIf="!preview; else previewImage">
          <button type="button" (click)="fileInput.click()" class="btn btn-primary">
            <i class="fa fa-image fa-4x align-middle"></i>
          </button>
          <input #fileInput type="file" hidden formControlName="file" accept="image/*" (change)="gravaEvento($event.target)"/>
          <app-mensagem mensagem="Por favor selecione a foto" *ngIf="!!formularioAnimal.get('file')?.errors?.required"></app-mensagem>
        </div>
        <ng-template #previewImage>
          <app-animal [url]="preview" title="Preview"></app-animal>
        </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-mensagem mensagem="Tamanho máximo do campo é 300 caracteres"
            *ngIf="!!formularioAnimal.get('description')?.errors?.maxlength">
          </app-mensagem>
          </div>
          <div class="form-group">
            <label class="text-muted">
              Permite comentario
                <input type="checkbox" formControlName="allowComments">
            </label>
          </div>
          <div *ngIf="!percentualConcluido; else uploaddiv">
              <button [disabled]="formularioAnimal.invalid" type="submit" class="btn btn-primary btn-block"
              >Enviar</button>

              <a routerLink="['animais']" class="btn btn-secondary btn-block">
                Cancelar
              </a>
          </div>
          <ng-template #uploaddiv>
            <div class="text-center display-4">
              Percentual de upload {{percentualConcluido}} %</div>
          </ng-template>
      </div>
  </form>
</div>

 import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { AnimaisService } from '../animais.service';
import { Router } from '@angular/router';
import { finalize } from 'rxjs/operators';
import { HttpEvent, HttpEventType } from '@angular/common/http';

@Component({
  selector: 'app-novo-animal',
  templateUrl: './novo-animal.component.html',
  styleUrls: ['./novo-animal.component.css']
})
export class NovoAnimalComponent implements OnInit {
  formularioAnimal!: FormGroup;
  file!: File;
  preview!: string;
  percentualConcluido = 0;

  constructor(
    private animaisService:AnimaisService,
    private fomBuilder: FormBuilder,
    private router: Router
    ) { }

  ngOnInit(): void {
    this.formularioAnimal = this.fomBuilder.group({
      file: ['',Validators.required],
      description: ['', Validators.maxLength(300)],
      allowComments: [true],
    })

  }

  upload(){
    const allowComments = this.formularioAnimal.get('allowComments')?.value ?? false;
    const description = this.formularioAnimal.get('description')?.value ?? '';

    this.animaisService.upload(description,allowComments,this.file)
      .pipe(finalize(() => this.router.navigate(['animais']))
      ).subscribe((event:HttpEvent<any>) =>{
        if(event.type === HttpEventType.UploadProgress){
          const total = event.total ?? 1;
          this.percentualConcluido = Math.round(100*(event.loaded / total));
        }
      }, (error)=> console.log(error)
      );
  }

  gravaEvento(arquivo: any): void{
    const [file] = arquivo?.files;
    this.file = file;
    const reader = new FileReader();
    reader.onload = (event:any)=>(this.preview=event.target.result);
    reader.readAsDataURL(file);
  }

}
1 resposta

Olá Raphael, tudo bem com você?

Peço desculpas pela demora em obter um retorno.

Realizei testes e simulações com o código disponibilizado em conjunto com o código da aula e o preview das imagens adicionadas foi apresentado corretamente, assim como a porcentagem de carregamento das imagens.

A exibição do carregamento das imagens, ocorre em um curto espaço de tempo pois, as imagens em sua maioria são pequenas (poucos mb ou kb), dessa forma o processamento ocorre de forma rápida. Uma alternativa para que a exibição da mensagem de carregamento permaneça sendo apresentada por mais tempo na tela, basta adicionar um delay para que seja aguardados alguns milissegundos antes de redirecionar o usuário.

Para isso, no arquivo novo-animal.component.ts no método upload adicione a chamada da função setTimeout() que será responsável por criar o delay de 300ms antes de redirecionar para a rota animais, deixando como apresentado abaixo:

.pipe(finalize(() => {
          setTimeout(() => {
            this.router.navigate(['animais']);
          }, 300);
        })
      )

Abaixo o método Upload com a mudança implementada:

upload() {
  const allowComments =
    this.formularioAnimal.get('allowComments')?.value ?? false;
  const description = this.formularioAnimal.get('description')?.value ?? '';

  this.animaisService
    .upload(description, allowComments, this.file)
    .pipe(
      finalize(() => {
        setTimeout(() => {
          this.router.navigate(['animais']);
        }, 300);
      })
    )
    .subscribe(
      (event: HttpEvent<any>) => {
        if (event.type === HttpEventType.UploadProgress) {
          const total = event.total ?? 1;
          this.percentualConcluido = Math.round(100 * (event.loaded / total));
        }
      },
      (error) => console.log(error)
    );
}

Quando ao botão cancelar, para que o usuário seja redirecionado para a página de exibição das imagens adicionadas, utilizaremos o routerLink da seguinte forma: routerLink="/animais". Basta modificar no arquivo novo-animal.component.html a tag a que contém o botão cancelar, deixando como abaixo :

<a routerLink="/animais" class="btn btn-secondary btn-block">
  Cancelar
</a>

Após realizar as mudanças salve os arquivos modificados. Reinicie a aplicação usando o comando ng serve e adicione uma nova imagem e verifique a apresentação da mensagem de carregamento.

Espero ter ajudado. Continue mergulhando em conhecimento e não hesite em voltar ao fórum para continuar aprendendo e interagindo com a comunidade.

Em caso de dúvidas estou à disposição.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software