3

I want to upload multiple file/images using angular v.7 (also angular material if it helps), and in the same formData will be included more data such as title or some text. I managed all this to work out but the problem is I can't get report progress per each file, instead the report I get is for all files together as one report.

How can I fix this?

HTML

<input type="file" id="mediaFile" #mediaFile multiple (change)="fileAdded($event)">

JS

this.selectedFiles: Files[] = [];

// when files are selected, save them in array selectedFiles
fileAdded(event) {
  if(event.target.files.length){
    for(let i=0 ; i < event.target.files.length ;i++){ 
      this.selectedFiles.push(<File>event.target.files[i]);
    }
  }
}


// upload data
upload() {
   this.message = "";
   // stop here if form is invalid
   if (this.shareForm.invalid) { this.message = "Fill the required fields"; return; }

   this.formD = new FormData();
   this.formD.append('firstname', this.shareForm.value.firstname);
   this.formD.append('lastname', this.shareForm.value.lastname);
   this.formD.append('position', this.shareForm.value.position);

   if(this.selectedFiles.length){
     for(let i=0 ; i < this.selectedFiles.length ; i++)
       this.formD.append('files[]', this.selectedFiles[i],this.selectedFiles[i].name);
   }

   this.loading = true;

   this.http.post<any>(myUrl, this.formD,{
    reportProgress: true,
    observe: 'events',
    withCredentials:true
  })
  .subscribe(
     res => {
       console.log(res)
       this.loading = false;
     },
     error => {
       this.message = error.message;
       this.loading = false;
    }
   );
}

I uploaded two files each one about 0.45MB, in the console i get this

{
  loaded: 868352,
  total: 976970,
  type: 1
}

I expect to get report progress per each file and not for all together

1 Answer 1

5

reportProgress will only work for the respective HTTP request, so when calling the function http.post with your formD form data object, it will only report the progress for that particular request containing all your data.

You will have to split the file upload into multiple requests in order to get progress for each individual upload process. This could be achieved by introducing a FormData array property, where each array entry contains only one individual file. Then, you could fire a request for each FormData instance, e.g. via creating your HTTP POST request observables first and then combining them via the RxJS forkJoin operator.

const httpRequests = this.formDataObjects.map((formData) => 
  this.http.post<any>(myUrl, formData,{
    reportProgress: true,
    observe: 'events',
    withCredentials:true
  })
);

forkJoin(httpRequests).subscribe(..*your subscription logic here..);
Sign up to request clarification or add additional context in comments.

3 Comments

suppose we are talking about a post (like in any social media). if I upload each file individually then how the server should know to which post the file belongs? - we still don't have post_id
@AlaaHliehel, you can add post_id in URL.
@ktretyak the problem was when creating a new post with several files, which means the post has not been created yet and there was no post_id

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.