1

I am trying to upload file in Angular 8 but getting below error and not able to figure it out

ERROR DOMException: "An attempt was made to use an object that is not, or is no longer, usable"

above error comes when I select a file. Below is my approach

Component.ts

import { Component, OnInit } from '@angular/core';
import {FormArray,FormBuilder,FormGroup,FormControl, Validators, NgForm} from "@angular/forms";
import { ApiService } from '../apis/commonapis';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
  userForm : FormGroup;
  constructor(private fb : FormBuilder,private service : ApiService) { }

  ngOnInit() {
    this.newForm(); 
  }
  newForm = function(){
    this.userForm = this.fb.group({
      email : ['',Validators.compose([Validators.required])],
      photo : ['',Validators.compose([Validators.required])]
    })
  }
  PostData(form: NgForm) {
    //console.log(form);
    var formData = new FormData();
    formData.append('photo', this.userForm.get('photo').value);
    console.log(formData);
    /*this.service.PostApi("http://localhost:1900/addUser",formData).subscribe(res=>{
                console.log(res);
                location.reload();
            });
     */
  }

  onFileSelect(event) { // here is some error
    if (event.target.files.length > 0) {
      const file = event.target.files[0];
      this.userForm.get('photo').setValue(file);
    }
  }
}

template file

<form [formGroup]="userForm" (ngSubmit)="PostData(userForm)" enctype="multipart/form-data"> 
        <div class="form-group row">
                <label for="email" class="col-sm-2 col-form-label">Email</label>
                <div class="col-sm-9">
                        <input type="text"  formControlName='email' class="form-control" required>
                </div>                                                                                                    
        </div>

        <div class="form-group row">
                <label for="photo" class="col-sm-2 col-form-label">Photo</label>
                <div class="col-sm-9">
                        <input type="file"  formControlName='photo' class="form-control" required  (change)="onFileSelect($event)">
                </div>                                                                                                    
        </div>

        <div class="form-group row">

                <div class="col-sm-10">
                        <input type="submit"  value='submit' class="form-control">
                </div>                                                                                                    
        </div>

</form>

I have searched for above error and it says this error comes when DOM is not loaded but here element is already loaded than why this error?

4
  • With an admittedly superficial read of your code, all seems good. I would suggest you create a StackBlitz showing the error so that the members of SO can help you dig further. Commented Aug 30, 2019 at 6:49
  • @dmcgrandle stackblitz.com/edit/angular-vmfh1t Commented Aug 30, 2019 at 10:38
  • 1
    @user1234 refer this answer stackoverflow.com/questions/55291422/… Commented Aug 31, 2019 at 8:42
  • @UshmiDave thanks a lot for paying attention to my problem :) Commented Aug 31, 2019 at 18:03

2 Answers 2

2

That error is strange. When I tested your code I received the following error:

Error: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

Just delete formControlName='photo' in your HTML template and should work.

EDIT

For displaying errors, you have to use a different approach than for regular inputs. File input doesn't have ng-touched, ng-untouched or ng-dirty classes, so you can't do something like:

<p *ngIf="photo.invalid && (photo.dirty || photo.touched)"> Show an error </p>

I suppose you want to display the error for the file input when the user hits the submit button. If so, you can do something like:

// add a property to your class
isPhotoError = false;

PostData(form: NgForm) {
    if (this.userForm.get('photo').invalid) {
      this.isPhotoError = true;
    }
    //do something
 }

photoErrorHandler() {
    if (this.userForm.get('photo').hasError('required')) {
      return 'Photo required';
    }
  }
<p *ngIf="isPhotoError"> {{ photoErrorHandler() }} </p>

Consider replacing your onFileSelect(event) with:

onFileSelect(event: Event) {
    const file = (event.target as HTMLInputElement).files[0];
    this.userForm.patchValue({ photo: file });
    this.userForm.get('photo').updateValueAndValidity();
  }

patchValue -> allows you to target a single control;

updateValueAndValidity() -> informs Angular that the value has been changed and it has to check if the value is valid or not.

I have created this StackBlitz to check the code (sorry about the styles). I have included an image preview if you need one in your project.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer but if i remove formControlName='photo'. Than how can i show errors related to this field.
1

I came to a similar problem. Just like Passionate Code mentioned in the comment, the solution was to remove formControlName from <input>. It seems to me that the problem arises from the fact that we are initializing the FormControl with an empty string and then we are trying to enter the File type object, maybe that some inner type validation is throwing the occurring exception. In my opinion, the best option is to skip the formControlName directive usage and write some custom validation.

Change this:

<div class="col-sm-9">
    <input type="text" formControlName='email' class="form-control" required>
</div>  

to this:

<div class="col-sm-9">
    <input type="text" class="form-control" required>
</div>  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.