0

I was explained (here btw) that using ViewChild I could access to a NgForm, its data, and be able to modify it before submit. So I have the following code:

@ViewChild('frmRegister',{static:true}) registerform: NgForm;

onRegister(form):void{

      this.authService.register(form.value).subscribe(res =>{
      this.router.navigateByUrl('/');
      })
  }

async file2Base64(archivo, origen) {
      const file = archivo.target.files[0];
      this.file2Base64result = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
      });
      if (origen == "avatar") this.registerform.value.avatar = this.file2Base64result;
      if (origen == "signature") this.registerform.value.signature = this.file2Base64result;
  }

and html goes like:

 <form #frmRegister="ngForm" class="login-container" (ngSubmit)="onRegister(registerform)">
//part of form
 <p><label name="signature">Firma Personal [PNG]</label>
        <input type="file" name="signature" placeholder="Firma Personal" ngModel (change)="file2Base64($event, 'signature')"></p>
      <p><label>Avatar</label>
        <input type="file" name="avatar" placeholder="Avatar" ngControl="avatar" ngModel (change)="file2Base64($event, 'avatar')"></p>
       <p><input type="submit" [disabled]="frmRegister.invalid" value="Register"></p>
    </form>

As you see, when the input file changes, file2Base64 is called. It should get the file and transform it into a base 64 string. However, When I submit it, the default value "C:/fakepath/image.png" is sent to the server. No matter what I do the default value overwrites the value I'm trying to overwrite, which is the base64 string.

Germán
  • 1,007
  • 1
  • 7
  • 20

2 Answers2

1

You cannot assign value with: this.registerform.value. BECAUSE the value of the control is for readonly.

What you can use is setValue or patchValue :

setValue method to update the control on any form to its new value, replacing the old value entirely.

Example:

this.registerform.controls['avatar'].setValue(this.file2Base64result);

patchValue : only updates properties that the form model defines.

Example:

this.registerform.patchValue({
  avatar: this.file2Base64result,
  signature: this.file2Base64result
});

And in the HTML Add those two hidden inputs as you suggested :

<input type="hidden" name="signature" ngModel/>
<input type="hidden" name="avatar" ngModel/>

For more information: https://angular.io/guide/reactive-forms

Oussail
  • 2,200
  • 11
  • 24
  • Do patchvalue and setvalue the same? – Germán Mar 02 '20 at 13:22
  • I have updated my answer with more pieces of information. – Oussail Mar 02 '20 at 13:25
  • As I'm trying to change the content of a input file, it tells me: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string. – Germán Mar 02 '20 at 13:45
  • Also, when trying patchValue: Property 'patchValue' does not exist on type 'NgForm'.ts(2339) – Germán Mar 02 '20 at 13:48
  • I'm sorry if my answer doesn't help you, I think you should edit the input value directly which is not possible. check this: https://stackoverflow.com/questions/1696877/how-to-set-a-value-to-a-file-input-in-html – Oussail Mar 02 '20 at 14:03
0

Using the information that @oussail provided, I created new hidden inputs in the form to pass them the transformed , and everything worked well.

 <input type="hidden" name="signature" ngModel/>
      <input type="hidden" name="avatar" ngModel/>
Germán
  • 1,007
  • 1
  • 7
  • 20