Búsqueda de sitios web

typescript - ¿Cómo guardar una imagen en el almacenamiento local usando un formulario reactivo de Angular?


Estoy construyendo un proyecto en Angular donde quiero subir una imagen usando un formulario reactivo de Angular y luego guardar esa imagen en el almacenamiento local.

A continuación se muestra el fragmento de código de "edit.component.html".

<form [formGroup]="form" (ngSubmit)="save()">
<label class="head1">Photo</label> <br>
<input type="file" formControlName="Photo">
<button [disabled]="form.invalid">Save</button>
</form>

A continuación se muestra el fragmento de código de "edit.component.ts".

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators, FormArray} from '@angular/forms';


@Component({
  selector: 'app-edit',
  templateUrl: './edit.component.html',
  styleUrls: ['./edit.component.css']
})
export class EditComponent {
form=new FormGroup({
    Photo:new FormControl(null,Validators.required),
});
save(){
    var profile;

    if(localStorage.getItem("profile")==null){
      profile={};
    }
    else{
      profile=JSON.parse(localStorage.getItem("profile")!);
    }
}
}

Cuando agregué esta línea const photo=this.form.get('Photo') as File; en la función save() del archivo ts, obtuve el error

Conversion of type 'AbstractControl<null, null> | null' to type 'File' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'AbstractControl<null, null>' is missing the following properties from type 'File': lastModified, name, webkitRelativePath, size, and 6 more.ts(2352)

Ahora por favor ayúdame modificando o agregando algún código para guardar la imagen en el almacenamiento local y también mostrar esa imagen obteniéndola del almacenamiento local en la página HTML.

Respuesta #1

Podrías convertir la imagen en una cadena con FileReader, porque el almacenamiento local maneja cadenas, y luego guardarla.

Y luego, podrías leerlo desde el almacenamiento local y convertirlo de nuevo en un archivo con File, y agregarlo al formulario.

Puedes configurar un detector de cambios en el campo de archivo, que obtendrá el archivo, lo asignará al formulario y lo guardará.

Aquí hay una demostración en Stackblitz

Puedes modificarlo según tus necesidades.

Métodos clave:

manejador de archivos:

  <input
    type="file"
    formControlName="Photo"
    (change)="handleFileInput($event)"
  />
  handleFileInput(event: Event) {
    const target = event.target as HTMLInputElement;

    const files = target.files as FileList;

    const file = files[0];

    this.form.value.Photo = file;

    this.saveFile(file);
  }

guardar archivo:

  saveFile(file: File) {
    const reader = new FileReader();

    reader.onloadend = () => {
      console.log(reader.result);

      this.preview = reader.result as string;

      localStorage.setItem('profile', reader.result as string);
    };
    reader.readAsDataURL(file);
  }

leer archivo:

 readFile() {
    const profile = localStorage.getItem('profile');

    console.log('reading ls image: ', profile);

    if (profile) {
      this.preview = profile;

      const contentType = profile.split(';')[0].replace('data:', '');

      const file = new File([profile], 'profile.jpeg', {
        type: contentType,
      });

      this.form.value.Photo = file;
    } else {
      this.preview = '';
    }
  }