Subir archivo en formularios

Avanzado
Angular
Angular
Actualizado: 27/08/2024

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Introducción

En esta lección crearemos un componente avatar desde el que poder subir una imagen de perfil al backend desde angular.

¿Te está gustando esta lección?

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Crear componente avatar

Ejecutar el comando:

ng generate component avatar-form --standalone

Variables y métodos para manejo del archivo

Se crean las variables:

  • photoFile que tendrá el archivo cargado por el usuario.
  • photoPreview que tendrá la imagen para previsualizarla por pantalla antes de subirla.

Resultado del archivo avatar-form.component.ts:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';

export interface User {
  id?: number;
  username?: string;
  email?: string;
  photoUrl?: string;
}

@Component({
  selector: 'app-avatar-form',
  standalone: true,
  imports: [],
  templateUrl: './avatar-form.component.html',
  styleUrl: './avatar-form.component.css'
})
export class AvatarFormComponent implements OnInit {

  photoFile: File | undefined;
  photoPreview: string | undefined;
  user: User | undefined;
  
  constructor(private httpClient: HttpClient) {}

  ngOnInit(): void {
    this.httpClient.get<User>('http://localhost:3000/user/account')
    .subscribe(user => this.user = user);
  }

  onFileChange(event: Event) {

  }

  save() {

  }
}

Métodos:

  • ngOnInit() carga el usuario autenticado para poder traer su avatar existente.
  • onFileChange() detectará la carga del archivo y lo guardará en las variables photoFile y photoPreview.
  • save() envía el archivo al backend.

Crear formulario HTML

En el archivo avatar-form.component.html se crea un formulario con bootstrap con un solo campo que permita cargar un archivo:

<div class="container">
    <div class="row">
        <div class="col-lg-8">
            <h1 class="my-5">Avatar de usuario</h1>
            <form>
                <div class="input-group mb-3">
                    <label class="input-group-text" for="photoUrl">Subir foto</label>
                    <input type="file" class="form-control" id="photoUrl" (change)="onFileChange($event)">
                </div>
                <button class="w-100 btn btn-primary btn-lg" type="button" (click)="save()">Subir avatar</button>
            </form>
        </div>
        <div class="col-lg-4">
            @if(photoPreview) {
            <h3 class="my-5">Nuevo avatar a subir</h3>
            <img class="img-fluid" [src]="photoPreview">
            }
            @if (!photoPreview && user?.photoUrl) {
            <h3 class="my-5">Avatar existente</h3>
            <img class="img-fluid" [src]="'http://localhost:3000/uploads/' + user?.photoUrl">
            }
        </div>
    </div>
</div>

En este HTML hay un solo input que permite cargar un archivo y automáticamente se invoca el método onFileChange() donde se gestionará el archivo.

Método onFileChange()

Este método guarda el archivo en una variable para poder subirlo más tarde en el método save() cuando el usuario pulse “Subir avatar”

También se encarga de leer el archivo para poder mostrarlo por pantalla.

  onFileChange(event: Event) {
    let target = event.target as HTMLInputElement;
    if (target.files !== null && target.files.length > 0) {
      this.photoFile = target.files[0]; // extraer el primer archivo

      // Opcional: Mostrar la imagen por pantalla para previsualizarla antes de subirla
      let reader = new FileReader();
      reader.onload = event => this.photoPreview = reader.result as string;
      reader.readAsDataURL(this.photoFile);
    }
  }

Este método solo lee un archivo. Si se quisiera leer más de uno entonces debe manejarse el array entero target.files.

Método save()

Este método es invocado cuando el usuario pulsa el botón de “Subir avatar”.

Carga el archivo en un objeto FormData y lo envía al backend.

  save() {
    if (!this.photoFile) return;

    let formData = new FormData();
    formData.append('file', this.photoFile);
    // si se quiere es posible agregar más información al formData provenientes de un formulario reactivo
    // Por ejemplo otros datos del usuario:
    // formData.append('address', this.userForm.get('address')?.value)

    this.httpClient.post<User>('http://localhost:3000/user/avatar', formData)
    .subscribe(user => {
      this.photoFile = undefined;
      this.photoPreview = undefined;
      this.user = user;
    });

  }

Se envía el archivo al método http://localhost:3000/user/avatar del backend.

Aprendizajes de esta lección

  • Crear un input de tipo file en HTML para cargar una imagen
  • Leer la imagen y mostrarla por pantalla
  • Enviar la imagen a backend con FormData

Completa Angular y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración